单链表删除、修改和查找
生活随笔
收集整理的這篇文章主要介紹了
单链表删除、修改和查找
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
相聲講究說學逗唱鏈表講究增刪改查
遍歷找到待修改節點 這里編號no不改變,把稱號和姓名重新賦值
public class SingleLinkedListDemo {public static void main(String[] args) {// TODO Auto-generated method stub 第一階段測試代碼// 創建節點HeroNode hero1 = new HeroNode(1, "呼保義", "宋江");HeroNode hero2 = new HeroNode(2, "玉麒麟", "盧俊義");HeroNode hero3 = new HeroNode(3, "智多星", "吳用");HeroNode hero4 = new HeroNode(4, "入云龍", "公孫勝");HeroNode hero5 = new HeroNode(5, "大刀", "關勝");// 創建單鏈表SingleLinkedList singleLinkedList = new SingleLinkedList();// 加入操作// singleLinkedList.add(hero1);
//
// singleLinkedList.add(hero2);
//
// singleLinkedList.add(hero3);
//
// singleLinkedList.add(hero4);
//
// singleLinkedList.add(hero5);singleLinkedList.addByOrder(hero1);singleLinkedList.addByOrder(hero2);singleLinkedList.addByOrder(hero4);singleLinkedList.addByOrder(hero3);singleLinkedList.addByOrder(hero5);// 顯示System.out.println("修改前:");singleLinkedList.list();HeroNode newHeroNode=new HeroNode(5, "寫輪眼", "卡卡西");singleLinkedList.update(newHeroNode);System.out.println("修改后:");singleLinkedList.list();}}//定義一個SingleLinkedList(單鏈表),管理英雄
class SingleLinkedList {// 一開始要初始化一個頭節點,保持不動否則會找不到剩下的節點,***不存放具體數據private HeroNode head = new HeroNode(0, "", "");// no初始化為0,姓名和稱號也不寫// 添加節點到單向鏈表// 當不考慮編號順序時:// 把節點添加進去的操作是首先找到當前鏈表的最后一個節點,next域原本是NULL,要把next域指向新添的節點public void add(HeroNode heroNode) {// 由于頭節點不能動,所以需要輔助變量HeroNode temp = head;// temp是輔助變量一開始指向頭節點,因為單向鏈表不是順序存儲,所以每一次找最后一個節點都需要遍歷整個鏈表// 開始遍歷while (true) {// 死循環if (temp.next == null) {// 找到鏈表的尾節點了break;}// 如果當前節點不是末節點// temp后移一位temp = temp.next;// 要清楚temp是一個移動輔助變量,每遍歷到一個不是尾節點的點temp就會指向當前節點的下一個節點}// 當退出這個死循環的時候,temp就指向了單鏈表的尾節點// 這個時候就可以把尾節點的next域指向傳入的新節點,這個新傳入的節點就連上了temp.next = heroNode;}// 按照順序顯示出來// 如果已經有這個編號,則添加失敗并給出提示public void addByOrder(HeroNode heroNode) {// heroNode為傳入的新節點// 由于頭節點不能動,所以需要輔助變量// 單鏈表要添加節點,temp一定是指向要插入位置的前一個節點,然后temp.next就指向新節點,這樣第一步就完成了HeroNode temp = head;boolean flag = false;// 判斷要添加的節點是否已存在while (true) {if (temp.next == null) {break;}if (temp.next.no > heroNode.no) {break;} else if (temp.next.no == heroNode.no) {flag = true;// 說明已經有了break;} else {temp = temp.next;// 如果上述情況都不符合的話,那么繼續遍歷找下一個節點}}// 退出循環的時候要看flag的值if (flag) {System.out.printf("已有編號%d,添加失敗~~~\n", heroNode.no);} else {// 可以插入到鏈表中,temp后移heroNode.next = temp.next;// 新節點的next域指向下一個節點temp.next = heroNode;// 前一個節點的next域指向新節點}}//修改節點的信息//根據編號no來修改稱號和姓名,編號no不動(如果編號改變就相當于添加操作了)public void update(HeroNode newHeroNode) {//判斷鏈表是否為空if(head.next==null) {System.out.println("鏈表為空~~~");return;}//找到需要修改的節點//根據編號no來修改節點信息//定義一個輔助變量HeroNode temp=head.next;boolean flag=false;//標識是否找到這個節點while(true) {if(temp==null) {//這里和之前不一樣,表示已經遍歷完這個鏈表了(無殘留,去干凈)break;}else if(temp.no==newHeroNode.no) {//表示已經找到要刪除的節點flag=true;break;}temp=temp.next;}//退出循環以后,根據flag的值來判斷if(flag) {//flag=true;表示找到了要修改的點temp.name=newHeroNode.name;temp.nickname=newHeroNode.nickname;}//還有一種情況就是沒有找到要修改的點else {System.out.println();System.out.printf("沒有找到編號為%d 的好漢,不能刪除😔\n");}}// 顯示單向鏈表public void list() {// 首先判斷鏈表是否為空if (head.next == null) {System.out.println("鏈表為空~~~");return;}// 如果能進行到下面這一步就說明鏈表不為空,至少有一個節點// 由于頭節點不能動,所以需要輔助變量HeroNode temp = head.next;// 至少有一個節點,所以就把輔助變量指向頭節點后的第一個節點while (true) {// 死循環if (temp == null) {// 找到鏈表的尾節點了break;}// 如果當前節點不是末節點System.out.println(temp);// 因為之前已經重寫過toString方法了,所以這里直接打印輸出就行了// ************// 下面這點很重要,每打印輸出一個節點,就需要將輔助變量temp后移,否則的話后果就是一直輸出一個值而且是個死循環temp = temp.next;}}}//定義HeroNode,每個HeroNode都是一個節點
class HeroNode {public int no;// 定義編號public String name;// 定義姓名public String nickname;// 定義稱號public HeroNode next;// 定義next域,指向下一個節點// 建一個構造器public HeroNode(int no, String nickname, String name) {this.no = no;this.nickname = nickname;this.name = name;}// 為了便于顯示,重寫toString方法/** @Override是偽代碼,表示重寫。(當然不寫@Override也可以),不過寫上有如下好處: 1、可以當注釋用,方便閱讀;* 2、編譯器可以給你驗證@Override下面的方法名是否是你父類中所有的,如果沒有則報錯。* 例如,你如果沒寫@Override,而你下面的方法名又寫錯了,這時你的編譯器是可以編譯通 過的,因為編譯器以為這個方法是你的子類中自己增加的方法。*/@Overridepublic String toString() {return "no= " + no + ",nickname= " + nickname + ",name = " + name;}}
搜索找到要刪除節點的前一個節點; temp.next=temp.next.next;(待刪除節點前一個節點的next域指向待刪除節點的下一個節點) 刪除的節點直接送到垃圾回收機制中,和新鏈表再無瓜葛。
public class SingleLinkedListDemo {public static void main(String[] args) {// TODO Auto-generated method stub 第一階段測試代碼// 創建節點HeroNode hero1 = new HeroNode(1, "呼保義", "宋江");HeroNode hero2 = new HeroNode(2, "玉麒麟", "盧俊義");HeroNode hero3 = new HeroNode(3, "智多星", "吳用");HeroNode hero4 = new HeroNode(4, "入云龍", "公孫勝");HeroNode hero5 = new HeroNode(5, "大刀", "關勝");// 創建單鏈表SingleLinkedList singleLinkedList = new SingleLinkedList();// 加入操作// singleLinkedList.add(hero1);
//
// singleLinkedList.add(hero2);
//
// singleLinkedList.add(hero3);
//
// singleLinkedList.add(hero4);
//
// singleLinkedList.add(hero5);singleLinkedList.addByOrder(hero1);singleLinkedList.addByOrder(hero2);singleLinkedList.addByOrder(hero4);singleLinkedList.addByOrder(hero3);singleLinkedList.addByOrder(hero5);// 修改操作HeroNode newHeroNode=new HeroNode(5, "寫輪眼", "卡卡西");singleLinkedList.update(newHeroNode);// 顯示System.out.println("刪除前:");singleLinkedList.list();// 修改操作singleLinkedList.del(1);System.out.println("刪除后:");singleLinkedList.list();}}//定義一個SingleLinkedList(單鏈表),管理英雄
class SingleLinkedList {// 一開始要初始化一個頭節點,保持不動否則會找不到剩下的節點,***不存放具體數據private HeroNode head = new HeroNode(0, "", "");// no初始化為0,姓名和稱號也不寫
// 添加節點到單向鏈表// 當不考慮編號順序時:// 把節點添加進去的操作是首先找到當前鏈表的最后一個節點,next域原本是NULL,要把next域指向新添的節點public void add(HeroNode heroNode) {// 由于頭節點不能動,所以需要輔助變量HeroNode temp = head;// temp是輔助變量一開始指向頭節點,因為單向鏈表不是順序存儲,所以每一次找最后一個節點都需要遍歷整個鏈表// 開始遍歷while (true) {// 死循環if (temp.next == null) {// 找到鏈表的尾節點了break;}// 如果當前節點不是末節點// temp后移一位temp = temp.next;// 要清楚temp是一個移動輔助變量,每遍歷到一個不是尾節點的點temp就會指向當前節點的下一個節點}// 當退出這個死循環的時候,temp就指向了單鏈表的尾節點// 這個時候就可以把尾節點的next域指向傳入的新節點,這個新傳入的節點就連上了temp.next = heroNode;}// 增添節點,按照順序顯示出來// 如果已經有這個編號,則添加失敗并給出提示public void addByOrder(HeroNode heroNode) {// heroNode為傳入的新節點// 由于頭節點不能動,所以需要輔助變量// 單鏈表要添加節點,temp一定是指向要插入位置的前一個節點,然后temp.next就指向新節點,這樣第一步就完成了HeroNode temp = head;boolean flag = false;// 判斷要添加的節點是否已存在while (true) {if (temp.next == null) {break;}if (temp.next.no > heroNode.no) {break;} else if (temp.next.no == heroNode.no) {flag = true;// 說明已經有了break;} else {temp = temp.next;// 如果上述情況都不符合的話,那么繼續遍歷找下一個節點}}// 退出循環的時候要看flag的值if (flag) {System.out.printf("已有編號%d,添加失敗~~~\n", heroNode.no);} else {// 可以插入到鏈表中,temp后移heroNode.next = temp.next;// 新節點的next域指向下一個節點temp.next = heroNode;// 前一個節點的next域指向新節點}}//修改節點的信息//根據編號no來修改稱號和姓名,編號no不動(如果編號改變就相當于添加操作了)public void update(HeroNode newHeroNode) {//判斷鏈表是否為空if(head.next==null) {System.out.println("鏈表為空~~~");return;}//找到需要修改的節點//根據編號no來修改節點信息//定義一個輔助變量HeroNode temp=head.next;boolean flag=false;//標識是否找到這個節點while(true) {if(temp==null) {//這里和之前不一樣,表示已經遍歷完這個鏈表了(無殘留,去干凈)break;}else if(temp.no==newHeroNode.no) {//表示已經找到要刪除的節點flag=true;break;}temp=temp.next;}//退出循環以后,根據flag的值來判斷if(flag) {//flag=true;表示找到了要修改的點temp.name=newHeroNode.name;temp.nickname=newHeroNode.nickname;}//還有一種情況就是沒有找到要修改的點else {System.out.println();System.out.printf("沒有找到編號為%d 的好漢,不能刪除😔\n");}}//刪除節點/**1.由于頭節點不能動,所以需要輔助變量,需要用輔助變量temp找到待刪除節點的前一個節點*比較時使用temp.next.no和待刪除節點的編號no比較**/public void del(int no) {HeroNode temp=head;//因為需要找到目標節點的前一個節點,所以這里不能把輔助節點定義為頭節點之后第一個節點boolean flag=false;while(true) {if(temp.next==null) {//到鏈表最后,最后一個節點的后面break;}else if(temp.next.no==no){//找到前一個節點flag=true;break;}temp=temp.next;//每遍歷一個節點就后移一位}if(flag) {//找到了前一個節點//刪除操作temp.next=temp.next.next;}else {System.out.println();System.out.printf("刪除的數據%d不存在呀不存在~~~\n",no);}}// 顯示單向鏈表public void list() {// 首先判斷鏈表是否為空if (head.next == null) {System.out.println("鏈表為空~~~");return;}// 如果能進行到下面這一步就說明鏈表不為空,至少有一個節點// 由于頭節點不能動,所以需要輔助變量HeroNode temp = head.next;// 至少有一個節點,所以就把輔助變量指向頭節點后的第一個節點while (true) {// 死循環if (temp == null) {// 找到鏈表的尾節點了break;}// 如果當前節點不是末節點System.out.println(temp);// 因為之前已經重寫過toString方法了,所以這里直接打印輸出就行了// ************// 下面這點很重要,每打印輸出一個節點,就需要將輔助變量temp后移,否則的話后果就是一直輸出一個值而且是個死循環temp = temp.next;}}}//定義HeroNode,每個HeroNode都是一個節點
class HeroNode {public int no;// 定義編號public String name;// 定義姓名public String nickname;// 定義稱號public HeroNode next;// 定義next域,指向下一個節點// 建一個構造器public HeroNode(int no, String nickname, String name) {this.no = no;this.nickname = nickname;this.name = name;}// 為了便于顯示,重寫toString方法/** @Override是偽代碼,表示重寫。(當然不寫@Override也可以),不過寫上有如下好處: 1、可以當注釋用,方便閱讀;* 2、編譯器可以給你驗證@Override下面的方法名是否是你父類中所有的,如果沒有則報錯。* 例如,你如果沒寫@Override,而你下面的方法名又寫錯了,這時你的編譯器是可以編譯通 過的,因為編譯器以為這個方法是你的子類中自己增加的方法。*/@Overridepublic String toString() {return "no= " + no + ",nickname= " + nickname + ",name = " + name;}}
上一篇blog里演示了單鏈表的增加節點的操作,下面演示單鏈表的刪除、修改和查找的操作。
修改操作:
思路:
刪除操作:
思想:
查找操作:貫穿再上述兩個操作之中,本質就是遍歷這個單鏈表,直到找到這個待查找的節點
未完待續。。。。
總結
以上是生活随笔為你收集整理的单链表删除、修改和查找的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 构造器是什么?(Java篇)
- 下一篇: 2022全球汽车集团十强排名出炉 丰田大