單鏈表的使用比較頻繁、重要,記錄一下學習到的相關操作
重點是輔助變量 temp 和標誌位 flag 的使用
創建節點類:
//定義 HeroNode, 每個 HeroNde 對象都是一個節點 class HeroNode{ public int no; public String name; public String nickname; public HeroNode next; //指向下一節點 //構造器 public HeroNode(int no, String name, String nickname){ this.no = no; this.name = name; this.nickname = nickname; } //顯示方法,重新 toString @Override public String toString() { return "HeroNode[no= "+ no +", name=" + name + ", nickname="+ nickname + "]"; } }
單鏈表按添加的順序,增加節點:
//添加節點到單向鏈表,添加的順序,即是鏈表中節點的順序 //當不考慮編號時: // 1、找到這個鏈表的最後節點 // 2、將這個節點的 next 指向新的節點 public void add(HeroNode heroNode){ //頭節點不能動,故用輔助變量 temp HeroNode temp = head; //遍歷鏈表,找到最後的節點 while(true){ //找到鏈表的最後 if(temp.next == null) break; //沒有找到,temp 後移 temp = temp.next; } //當結束 while 循環時,temp指向 鏈表的最後 //將這最後的節點的 next 指向 新的節點(即要添加進鏈表的節點:heroNode) temp.next = heroNode; }
根據排名插入節點,即插入節點會自動排序
//根據排名添加英雄,自動排序,如果已經有,則提示添加失敗,並給出提示 public void addByOrder(HeroNode heroNode){ //頭節點不能使用,需要通過輔助指針來幫助找到添加的位置 //temp 添加位置前一個的節點 //flag 標記想要添加的編號是否存在,默認爲 false HeroNode temp = head; boolean flag = false; while(true){ //爲 null 說明temp已經在鏈表的最後,故退出 if(temp.next == null) break; // > 說明想要的位置已經找到: // 按從小到大排列的,所以後一個節點,應該比待添加節點的序號大 // = 說明已經存在這個節點(位置在當前temp的下一個節點),所以將 flag 值改變後退出,並返回提示信息 if(temp.next.no > heroNode.no) { break; }else if(temp.next.no == heroNode.no){ flag = true; break; } //未查到合適的添加位置,後移一位,遍歷當前鏈表 temp = temp.next; } if(flag) { System.out.printf("準備插入的英雄編號: %d 已經存在, 不能加入\n", heroNode.no); }else { //插入到鏈表中,temp的後面 heroNode.next = temp.next; temp.next = heroNode; } }
修改節點內容:
public void updata(HeroNode newHeroNode){ //判斷鏈表是否爲空 if(head.next == null) { System.out.println("鏈表爲空"); return; } //定義輔助指針 temp 與 標誌 flag,默認值爲:false HeroNode temp = head; boolean flag = false; //遍歷 while(true){ //遍歷完都沒有找到 if(temp.next == null) break; //找到了,把 flag 置爲 true if(temp.next.no == newHeroNode.no){ flag = true; break; } //遍歷 temp = temp.next; } //退出了 while 要麼找到,要麼沒找到,由 flag 來判斷 if(flag){ temp.next.name = newHeroNode.name; temp.next.nickname = newHeroNode.nickname; } else{ System.out.printf("未找到編號爲: %d 的節點,不能修改", temp.no); } }
刪除節點:
public void del(int no){ HeroNode temp = head; boolean flag = false; while(true){ if(temp.next == null) break; if(temp.next.no == no){ flag = true; break; } temp = temp.next; } if(flag){ temp.next = temp.next.next; } else{ System.out.printf("你想要刪除的節點 %d 不存在,刪除失敗", no); } }
總的全部代碼(包括測試):
package com.chen; /** * @author 淡 * @create 2020-02-09 13:49 */ public class linkedlist { public static void main(String[] args) { //測試 //創建節點 HeroNode hero1 = new HeroNode(1, "宋江", "及時雨"); HeroNode hero2 = new HeroNode(2, "盧俊義", "玉麒麟"); HeroNode hero3 = new HeroNode(3, "吳用", "智多星"); HeroNode hero4 = new HeroNode(4, "林沖", "豹子頭"); //創建鏈表 SingleLinkedList singleLinkedList = new SingleLinkedList(); //英雄加入鏈表 // singleLinkedList.add(hero1); // singleLinkedList.add(hero3); // singleLinkedList.add(hero4); // singleLinkedList.add(hero2); //英雄加入鏈表 singleLinkedList.addByOrder(hero1); singleLinkedList.addByOrder(hero3); singleLinkedList.addByOrder(hero4); singleLinkedList.addByOrder(hero2); singleLinkedList.addByOrder(hero3); //顯示鏈表 singleLinkedList.list(); HeroNode newHeroNode = new HeroNode(2,"小盧","玉麒麟~~"); singleLinkedList.updata(newHeroNode); System.out.println("修改後的鏈表:"); singleLinkedList.list(); singleLinkedList.del(1); singleLinkedList.del(4); singleLinkedList.del(2); singleLinkedList.del(3); System.out.println("刪除後的鏈表:"); singleLinkedList.list(); } } //定義 SingleLinkedList 管理我們的英雄 class SingleLinkedList{ //初始化一個頭節點,不放任何數據 private HeroNode head = new HeroNode(0, "", ""); //添加節點到單向鏈表,添加的順序,即是鏈表中節點的順序 //當不考慮編號時: // 1、找到這個鏈表的最後節點 // 2、將這個節點的 next 指向新的節點 public void add(HeroNode heroNode){ //頭節點不能動,故用輔助變量 temp HeroNode temp = head; //遍歷鏈表,找到最後的節點 while(true){ //找到鏈表的最後 if(temp.next == null) break; //沒有找到,temp 後移 temp = temp.next; } //當結束 while 循環時,temp指向 鏈表的最後 //將這最後的節點的 next 指向 新的節點(即要添加進鏈表的節點:heroNode) temp.next = heroNode; } //根據排名添加英雄,自動排序,如果已經有,則提示添加失敗,並給出提示 public void addByOrder(HeroNode heroNode){ //頭節點不能使用,需要通過輔助指針來幫助找到添加的位置 //temp 添加位置前一個的節點 //flag 標記想要添加的編號是否存在,默認爲 false HeroNode temp = head; boolean flag = false; while(true){ //爲 null 說明temp已經在鏈表的最後,故退出 if(temp.next == null) break; // > 說明想要的位置已經找到: // 按從小到大排列的,所以後一個節點,應該比待添加節點的序號大 // = 說明已經存在這個節點(位置在當前temp的下一個節點),所以將 flag 值改變後退出,並返回提示信息 if(temp.next.no > heroNode.no) { break; }else if(temp.next.no == heroNode.no){ flag = true; break; } //未查到合適的添加位置,後移一位,遍歷當前鏈表 temp = temp.next; } if(flag) { System.out.printf("準備插入的英雄編號: %d 已經存在, 不能加入\n", heroNode.no); }else { //插入到鏈表中,temp的後面 heroNode.next = temp.next; temp.next = heroNode; } } public void updata(HeroNode newHeroNode){ //判斷鏈表是否爲空 if(head.next == null) { System.out.println("鏈表爲空"); return; } //定義輔助指針 temp 與 標誌 flag,默認值爲:false HeroNode temp = head; boolean flag = false; //遍歷 while(true){ //遍歷完都沒有找到 if(temp.next == null) break; //找到了,把 flag 置爲 true if(temp.next.no == newHeroNode.no){ flag = true; break; } //遍歷 temp = temp.next; } //退出了 while 要麼找到,要麼沒找到,由 flag 來判斷 if(flag){ temp.next.name = newHeroNode.name; temp.next.nickname = newHeroNode.nickname; } else{ System.out.printf("未找到編號爲: %d 的節點,不能修改", temp.no); } } public void del(int no){ HeroNode temp = head; boolean flag = false; while(true){ if(temp.next == null) break; if(temp.next.no == no){ flag = true; break; } temp = temp.next; } if(flag){ temp.next = temp.next.next; } else{ System.out.printf("你想要刪除的節點 %d 不存在,刪除失敗", 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); // temp 後移到下一節點 temp = temp.next; } } } //定義 HeroNode, 每個 HeroNde 對象都是一個節點 class HeroNode{ public int no; public String name; public String nickname; public HeroNode next; //指向下一節點 //構造器 public HeroNode(int no, String name, String nickname){ this.no = no; this.name = name; this.nickname = nickname; } //顯示方法,重新 toString @Override public String toString() { return "HeroNode[no= "+ no +", name=" + name + ", nickname="+ nickname + "]"; } }