成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Java如何實現單向鏈表

這篇文章將為大家詳細講解有關Java如何實現單向鏈表,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

創(chuàng)新互聯建站從2013年成立,是專業(yè)互聯網技術服務公司,擁有項目做網站、成都做網站網站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元銅川做網站,已為上家服務,為銅川各地企業(yè)和個人服務,聯系電話:028-86922220

一、前言

最近在回顧數據結構與算法,有部分的算法題用到了棧的思想,說起棧又不得不說鏈表了。數組和鏈表都是線性存儲結構的基礎,棧和隊列都是線性存儲結構的應用~

二、回顧與知新

說起鏈表,我們先提一下數組吧,跟數組比較一下就很理解鏈表這種存儲結構了。

2.1回顧數組

數組我們無論是C、Java都會學過:

  • 數組是一種連續(xù)存儲線性結構,元素類型相同,大小相等

Java如何實現單向鏈表

數組的優(yōu)點:

  • 存取速度快

數組的缺點:

  • 事先必須知道數組的長度

  • 插入刪除元素很慢

  • 空間通常是有限制的

  • 需要大塊連續(xù)的內存塊

  • 插入刪除元素的效率很低

2.2鏈表說明

看完了數組,回到我們的鏈表:

  • 鏈表是離散存儲線性結構

n個節(jié)點離散分配,彼此通過指針相連,每個節(jié)點只有一個前驅節(jié)點,每個節(jié)點只有一個后續(xù)節(jié)點,首節(jié)點沒有前驅節(jié)點,尾節(jié)點沒有后續(xù)節(jié)點。

Java如何實現單向鏈表

鏈表優(yōu)點:

  • 空間沒有限制

  • 插入刪除元素很快

鏈表缺點:

  • 存取速度很慢

鏈表相關術語介紹,我還是通過上面那個圖來說明吧:

Java如何實現單向鏈表

確定一個鏈表我們只需要頭指針,通過頭指針就可以把整個鏈表都能推導出來了~

鏈表又分了好幾類:

1、單向鏈表

  • 一個節(jié)點指向下一個節(jié)點

2、雙向鏈表

  • 一個節(jié)點有兩個指針域

3、循環(huán)鏈表

  • 能通過任何一個節(jié)點找到其他所有的節(jié)點,將兩種(雙向/單向)鏈表的最后一個結點指向第一個結點從而實現循環(huán)

操作鏈表要時刻記住的是:

節(jié)點中指針域指向的就是一個節(jié)點了!

三、Java實現鏈表

算法:

  • 遍歷

  • 查找

  • 清空

  • 銷毀

  • 求長度

  • 排序

  • 刪除節(jié)點

  • 插入節(jié)點

首先,我們定義一個類作為節(jié)點

  • 數據域

  • 指針域

為了操作方便我就直接定義成public了。

public class Node {

 //數據域
 public int data;
 //指針域,指向下一個節(jié)點
 public Node next;
 public Node() {
 }

 public Node(int data) {
 this.data = data;
 }

 public Node(int data, Node next) {
 this.data = data;
 this.next = next;
 }
}

3.1創(chuàng)建鏈表(增加節(jié)點)

向鏈表中插入數據:

  • 找到尾節(jié)點進行插入

  • 即使頭節(jié)點.next為null,不走while循環(huán),也是將頭節(jié)點與新節(jié)點連接的(我已經將head節(jié)點初始化過了,因此沒必要判斷頭節(jié)點是否為null)~

 /**
 * 向鏈表添加數據
 *
 * @param value 要添加的數據
 */
 public static void addData(int value) {
 //初始化要加入的節(jié)點
 Node newNode = new Node(value);
 //臨時節(jié)點
 Node temp = head;
 // 找到尾節(jié)點
 while (temp.next != null) {
 temp = temp.next;
 }
 // 已經包括了頭節(jié)點.next為null的情況了~
 temp.next = newNode;
 }

3.2遍歷鏈表

上面我們已經編寫了增加方法,現在遍歷一下看一下是否正確~~~

從首節(jié)點開始,不斷往后面找,直到后面的節(jié)點沒有數據:

 /**
 * 遍歷鏈表
 *
 * @param head 頭節(jié)點
 */
 public static void traverse(Node head) {
 //臨時節(jié)點,從首節(jié)點開始
 Node temp = head.next;
 while (temp != null) {
 System.out.println("關注公眾號Java3y:" + temp.data);
 //繼續(xù)下一個
 temp = temp.next;
 }
 }

結果:

Java如何實現單向鏈表 

3.3插入節(jié)點

  • 插入一個節(jié)點到鏈表中,首先得判斷這個位置是否是合法的,才能進行插入~

  • 找到想要插入的位置的上一個節(jié)點就可以了~

 /**
 * 插入節(jié)點
 *
 * @param head 頭指針
 * @param index 要插入的位置
 * @param value 要插入的值
 */
 public static void insertNode(Node head, int index, int value) {
 //首先需要判斷指定位置是否合法,
 if (index < 1 || index > linkListLength(head) + 1) {
 System.out.println("插入位置不合法。");
 return;
 }
 //臨時節(jié)點,從頭節(jié)點開始
 Node temp = head;
 //記錄遍歷的當前位置
 int currentPos = 0;
 //初始化要插入的節(jié)點
 Node insertNode = new Node(value);
 while (temp.next != null) {
 //找到上一個節(jié)點的位置了
 if ((index - 1) == currentPos) {
 //temp表示的是上一個節(jié)點
 //將原本由上一個節(jié)點的指向交由插入的節(jié)點來指向
 insertNode.next = temp.next;
 //將上一個節(jié)點的指針域指向要插入的節(jié)點
 temp.next = insertNode;
 return;
 }
 currentPos++;
 temp = temp.next;
 }
 }

3.4獲取鏈表的長度

獲取鏈表的長度就很簡單了,遍歷一下,每得到一個節(jié)點+1即可~

 /**
 * 獲取鏈表的長度
 * @param head 頭指針
 */
 public static int linkListLength(Node head) {
 int length = 0;
 //臨時節(jié)點,從首節(jié)點開始
 Node temp = head.next;
 // 找到尾節(jié)點
 while (temp != null) {
 length++;
 temp = temp.next;
 }
 return length;
 }

3.5刪除節(jié)點

刪除某個位置上的節(jié)點其實是和插入節(jié)點很像的, 同樣都要找到上一個節(jié)點。將上一個節(jié)點的指針域改變一下,就可以刪除了~

 /**
 * 根據位置刪除節(jié)點
 *
 * @param head 頭指針
 * @param index 要刪除的位置
 */
 public static void deleteNode(Node head, int index) {
 //首先需要判斷指定位置是否合法,
 if (index < 1 || index > linkListLength(head) + 1) {
  System.out.println("刪除位置不合法。");
  return;
 }

 //臨時節(jié)點,從頭節(jié)點開始
 Node temp = head;
 //記錄遍歷的當前位置
 int currentPos = 0;
 while (temp.next != null) {
  //找到上一個節(jié)點的位置了
  if ((index - 1) == currentPos) {
  //temp表示的是上一個節(jié)點
  //temp.next表示的是想要刪除的節(jié)點
  //將想要刪除的節(jié)點存儲一下
  Node deleteNode = temp.next;
  //想要刪除節(jié)點的下一個節(jié)點交由上一個節(jié)點來控制
  temp.next = deleteNode.next;
  //Java會回收它,設置不設置為null應該沒多大意義了(個人覺得,如果不對請指出哦~)
  deleteNode = null;
  return;
  }
  currentPos++;
  temp = temp.next;
 }
 }

3.6對鏈表進行排序

前面已經講過了8種的排序算法了【八種排序算法總結】,這次挑簡單的冒泡排序吧(其實我是想寫快速排序的,嘗試了一下感覺有點難.....)

 /**
 * 對鏈表進行排序
 *
 * @param head
 *
 */
 public static void sortLinkList(Node head) {
 Node currentNode;
 Node nextNode;
 for (currentNode = head.next; currentNode.next != null; currentNode = currentNode.next) {
  for (nextNode = head.next; nextNode.next != null; nextNode = nextNode.next) {
  if (nextNode.data > nextNode.next.data) {
   int temp = nextNode.data;
   nextNode.data = nextNode.next.data;
   nextNode.next.data = temp;
  }
  }
 }
 }

3.7找到鏈表中倒數第k個節(jié)點

這個算法挺有趣的:設置兩個指針p1、p2,讓p2比p1快k個節(jié)點,同時向后遍歷,當p2為空,則p1為倒數第k個節(jié)點

 /**
 * 找到鏈表中倒數第k個節(jié)點(設置兩個指針p1、p2,讓p2比p1快k個節(jié)點,同時向后遍歷,當p2為空,則p1為倒數第k個節(jié)點
 *
 * @param head
 * @param k 倒數第k個節(jié)點
 */
 public static Node findKNode(Node head, int k) {
 if (k < 1 || k > linkListLength(head))
  return null;
 Node p1 = head;
 Node p2 = head;
 // p2比怕p1快k個節(jié)點
 for (int i = 0; i < k - 1; i++)
  p2 = p2.next;
 // 只要p2為null,那么p1就是倒數第k個節(jié)點了
 while (p2.next != null) {

  p2 = p2.next;
  p1 = p1.next;
 }
 return p1;
 }

3.8刪除鏈表重復數據

跟冒泡排序差不多,只要它相等,就能刪除了~

 /**
 * 刪除鏈表重復數據(跟冒泡差不多,等于刪除就是了)
 *
 * @param head 頭節(jié)點
 */
 public static void deleteDuplecate(Node head) {
 //臨時節(jié)點,(從首節(jié)點開始-->真正有數據的節(jié)點)
 Node temp = head.next;

 //當前節(jié)點(首節(jié)點)的下一個節(jié)點
 Node nextNode = temp.next;
 while (temp.next != null) {
  while (nextNode.next != null) {
  if (nextNode.next.data == nextNode.data) {
   //將下一個節(jié)點刪除(當前節(jié)點指向下下個節(jié)點)
   nextNode.next = nextNode.next.next;
  } else {

   //繼續(xù)下一個
   nextNode = nextNode.next;
  }
  }
  //下一輪比較
  temp = temp.next;
 }
 }

3.9查詢鏈表的中間節(jié)點

這個算法也挺有趣的:一個每次走1步,一個每次走兩步,走兩步的遍歷完,然后走一步的指針,那就是中間節(jié)點

 /**
 * 查詢單鏈表的中間節(jié)點
 */
 public static Node searchMid(Node head) {
 Node p1 = head;
 Node p2 = head;
 // 一個走一步,一個走兩步,直到為null,走一步的到達的就是中間節(jié)點
 while (p2 != null && p2.next != null && p2.next.next != null) {
  p1 = p1.next;
  p2 = p2.next.next;
 }
 return p1;
 }

3.10通過遞歸從尾到頭輸出單鏈表

 /**
 * 通過遞歸從尾到頭輸出單鏈表
 *
 * @param head 頭節(jié)點
 */
 public static void printListReversely(Node head) {
 if (head != null) {
  printListReversely(head.next);
  System.out.println(head.data);
 }
 }

3.11反轉鏈表

 /**
 * 實現鏈表的反轉
 *
 * @param node 鏈表的頭節(jié)點
 */
 public static Node reverseLinkList(Node node) {
 Node prev ;
 if (node == null || node.next == null) {
  prev = node;
 } else {
  Node tmp = reverseLinkList(node.next);
  node.next.next = node;
  node.next = null;
  prev = tmp;
 }
 return prev;
 }

Java如何實現單向鏈表

反轉鏈表參考自:https://www.jb51.net/article/136185.htm

四、最后

理解鏈表本身并不難,但做相關的操作就弄得頭疼,head.next next next next ....(算法這方面我還是薄弱啊..腦子不夠用了.....)寫了兩天就寫了這么點東西...

操作一個鏈表只需要知道它的頭指針就可以做任何操作了

1、添加數據到鏈表中

  • 遍歷找到尾節(jié)點,插入即可(只要while(temp.next != null),退出循環(huán)就會找到尾節(jié)點)

2、遍歷鏈表

  • 從首節(jié)點(有效節(jié)點)開始,只要不為null,就輸出

3、給定位置插入節(jié)點到鏈表中

  • 首先判斷該位置是否有效(在鏈表長度的范圍內)

  • 找到想要插入位置的上一個節(jié)點
     將原本由上一個節(jié)點的指向交由插入的節(jié)點來指向
     上一個節(jié)點指針域指向想要插入的節(jié)點

  • Java如何實現單向鏈表

4、獲取鏈表的長度

  • 每訪問一次節(jié)點,變量++操作即可

5、刪除給定位置的節(jié)點

  • 首先判斷該位置是否有效(在鏈表長度的范圍內)

  • 找到想要插入位置的上一個節(jié)點
     將原本由上一個節(jié)點的指向后面一個節(jié)點

  • Java如何實現單向鏈表

6、對鏈表進行排序

  • 使用冒泡算法對其進行排序

7、找到鏈表中倒數第k個節(jié)點

  • 設置兩個指針p1、p2,讓p2比p1快k個節(jié)點,同時向后遍歷,當p2為空,則p1為倒數第k個節(jié)點

8、刪除鏈表重復數據

  • 操作跟冒泡排序差不多,只要它相等,就能刪除了~

9、查詢鏈表的中間節(jié)點

  • 這個算法也挺有趣的:一個每次走1步,一個每次走兩步,走兩步的遍歷完,然后走一步的指針,那就是中間節(jié)點

10、遞歸從尾到頭輸出單鏈表

  • 只要下面還有數據,那就往下找,遞歸是從最后往前翻。

11、反轉鏈表

  • 有遞歸和非遞歸兩種方式,我覺得是挺難的。可以到我給出的鏈接上查閱~

PS:每個人的實現都會不一樣,所以一些小細節(jié)難免會有些變動,也沒有固定的寫法,能夠實現對應的功能即可~

關于“Java如何實現單向鏈表”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

網站標題:Java如何實現單向鏈表
網站網址:http://jinyejixie.com/article2/jjhcoc.html

成都網站建設公司_創(chuàng)新互聯,為您提供微信公眾號、網站收錄、品牌網站建設、外貿建站、電子商務

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯

外貿網站建設
康定县| 靖江市| 随州市| 保山市| 吉林省| 香格里拉县| 都匀市| 刚察县| 张北县| 灵璧县| 和林格尔县| 益阳市| 台山市| 白水县| 水城县| 六盘水市| 武夷山市| 五华县| 磐安县| 托克托县| 鸡西市| 平罗县| 封开县| 榆树市| 博客| 咸宁市| 万全县| 长汀县| 巴林右旗| 隆德县| 孟州市| 沙河市| 浮山县| 南川市| 常山县| 恩平市| 东兴市| 麦盖提县| 土默特左旗| 内江市| 慈利县|