安裝yum, python3, pip3 , rocketmq客戶端 攻略
阿新 • • 發佈:2020-12-24
package com.atguigu.linkedlist; import java.util.Stack; public class SingleLinkedListDemo { 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(hero4); singleLinkedList.add(hero2); singleLinkedList.add(hero3); // 測試一下單鏈表的反轉功能 System.out.println("原來連結串列的情況~~"); singleLinkedList.list(); // System.out.println("反轉單鏈表~~"); // reversetList(singleLinkedList.getHead()); // singleLinkedList.list(); System.out.println("測試逆序列印單鏈表, 沒有改變連結串列的結構~~"); reversePrint(singleLinkedList.getHead()); /* //加入按照編號的順序 singleLinkedList.addByOrder(hero1); singleLinkedList.addByOrder(hero4); singleLinkedList.addByOrder(hero2); singleLinkedList.addByOrder(hero3); //顯示一把 singleLinkedList.list(); //測試修改節點的程式碼 HeroNode newHeroNode = new HeroNode(2, "小盧", "玉麒麟~~"); singleLinkedList.update(newHeroNode); System.out.println("修改後的連結串列情況~~"); singleLinkedList.list(); //刪除一個節點 singleLinkedList.del(1); singleLinkedList.del(4); System.out.println("刪除後的連結串列情況~~"); singleLinkedList.list(); //測試一下 求單鏈表中有效節點的個數 System.out.println("有效的節點個數=" + getLength(singleLinkedList.getHead()));//2 //測試一下看看是否得到了倒數第K個節點 HeroNode res = findLastIndexNode(singleLinkedList.getHead(), 3); System.out.println("res=" + res); */ } //方式2: //可以利用棧這個資料結構,將各個節點壓入到棧中,然後利用棧的先進後出的特點,就實現了逆序列印的效果 public static void reversePrint(HeroNode head) { if(head.next == null) { return;//空連結串列,不能列印 } //建立要給一個棧,將各個節點壓入棧 Stack<HeroNode> stack = new Stack<HeroNode>(); HeroNode cur = head.next; //將連結串列的所有節點壓入棧 while(cur != null) { stack.push(cur); cur = cur.next; //cur後移,這樣就可以壓入下一個節點 } //將棧中的節點進行列印,pop 出棧 while (stack.size() > 0) { System.out.println(stack.pop()); //stack的特點是先進後出 } } //將單鏈表反轉 public static void reversetList(HeroNode head) { //如果當前連結串列為空,或者只有一個節點,無需反轉,直接返回 if(head.next == null || head.next.next == null) { return ; } //定義一個輔助的指標(變數),幫助我們遍歷原來的連結串列 HeroNode cur = head.next; HeroNode next = null;// 指向當前節點[cur]的下一個節點 HeroNode reverseHead = new HeroNode(0, "", ""); //遍歷原來的連結串列,每遍歷一個節點,就將其取出,並放在新的連結串列reverseHead 的最前端 //動腦筋 while(cur != null) { next = cur.next;//先暫時儲存當前節點的下一個節點,因為後面需要使用 cur.next = reverseHead.next;//將cur的下一個節點指向新的連結串列的最前端 reverseHead.next = cur; //將cur 連線到新的連結串列上 cur = next;//讓cur後移 } //將head.next 指向 reverseHead.next , 實現單鏈表的反轉 head.next = reverseHead.next; } //查詢單鏈表中的倒數第k個結點 【新浪面試題】 //思路 //1. 編寫一個方法,接收head節點,同時接收一個index //2. index 表示是倒數第index個節點 //3. 先把連結串列從頭到尾遍歷,得到連結串列的總的長度 getLength //4. 得到size 後,我們從連結串列的第一個開始遍歷 (size-index)個,就可以得到 //5. 如果找到了,則返回該節點,否則返回nulll public static HeroNode findLastIndexNode(HeroNode head, int index) { //判斷如果連結串列為空,返回null if(head.next == null) { return null;//沒有找到 } //第一個遍歷得到連結串列的長度(節點個數) int size = getLength(head); //第二次遍歷 size-index 位置,就是我們倒數的第K個節點 //先做一個index的校驗 if(index <=0 || index > size) { return null; } //定義給輔助變數, for 迴圈定位到倒數的index HeroNode cur = head.next; //3 // 3 - 1 = 2 for(int i =0; i< size - index; i++) { cur = cur.next; } return cur; } //方法:獲取到單鏈表的節點的個數(如果是帶頭結點的連結串列,需求不統計頭節點) /** * * @param head 連結串列的頭節點 * @return 返回的就是有效節點的個數 */ public static int getLength(HeroNode head) { if(head.next == null) { //空連結串列 return 0; } int length = 0; //定義一個輔助的變數, 這裡我們沒有統計頭節點 HeroNode cur = head.next; while(cur != null) { length++; cur = cur.next; //遍歷 } return length; } } //定義SingleLinkedList 管理我們的英雄 class SingleLinkedList { //先初始化一個頭節點, 頭節點不要動, 不存放具體的資料 private HeroNode head = new HeroNode(0, "", ""); //返回頭節點 public HeroNode getHead() { return head; } //新增節點到單向連結串列 //思路,當不考慮編號順序時 //1. 找到當前連結串列的最後節點 //2. 將最後這個節點的next 指向 新的節點 public void add(HeroNode heroNode) { //因為head節點不能動,因此我們需要一個輔助遍歷 temp HeroNode temp = head; //遍歷連結串列,找到最後 while(true) { //找到連結串列的最後 if(temp.next == null) {// break; } //如果沒有找到最後, 將將temp後移 temp = temp.next; } //當退出while迴圈時,temp就指向了連結串列的最後 //將最後這個節點的next 指向 新的節點 temp.next = heroNode; } //第二種方式在新增英雄時,根據排名將英雄插入到指定位置 //(如果有這個排名,則新增失敗,並給出提示) public void addByOrder(HeroNode heroNode) { //因為頭節點不能動,因此我們仍然通過一個輔助指標(變數)來幫助找到新增的位置 //因為單鏈表,因為我們找的temp 是位於 新增位置的前一個節點,否則插入不了 HeroNode temp = head; boolean flag = false; // flag標誌新增的編號是否存在,預設為false while(true) { if(temp.next == null) {//說明temp已經在連結串列的最後 break; // } if(temp.next.no > heroNode.no) { //位置找到,就在temp的後面插入 break; } else if (temp.next.no == heroNode.no) {//說明希望新增的heroNode的編號已然存在 flag = true; //說明編號存在 break; } temp = temp.next; //後移,遍歷當前連結串列 } //判斷flag 的值 if(flag) { //不能新增,說明編號存在 System.out.printf("準備插入的英雄的編號 %d 已經存在了, 不能加入\n", heroNode.no); } else { //插入到連結串列中, temp的後面 heroNode.next = temp.next; temp.next = heroNode; } } //修改節點的資訊, 根據no編號來修改,即no編號不能改. //說明 //1. 根據 newHeroNode 的 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; //已經遍歷完連結串列 } if(temp.no == newHeroNode.no) { //找到 flag = true; break; } temp = temp.next; } //根據flag 判斷是否找到要修改的節點 if(flag) { temp.name = newHeroNode.name; temp.nickname = newHeroNode.nickname; } else { //沒有找到 System.out.printf("沒有找到 編號 %d 的節點,不能修改\n", newHeroNode.no); } } //刪除節點 //思路 //1. head 不能動,因此我們需要一個temp輔助節點找到待刪除節點的前一個節點 //2. 說明我們在比較時,是temp.next.no 和 需要刪除的節點的no比較 public void del(int no) { HeroNode temp = head; boolean flag = false; // 標誌是否找到待刪除節點的 while(true) { if(temp.next == null) { //已經到連結串列的最後 break; } if(temp.next.no == no) { //找到的待刪除節點的前一個節點temp flag = true; break; } temp = temp.next; //temp後移,遍歷 } //判斷flag if(flag) { //找到 //可以刪除 temp.next = temp.next.next; }else { 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); //將temp後移, 一定小心 temp = temp.next; } } } //定義HeroNode , 每個HeroNode 物件就是一個節點 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 + "]"; } }