鏈表(Linked List)之單鏈表

原文地址:傳送門

鏈表(Linked List)介紹

鏈表是有序的列表,但是它在內存中是存儲如下

img

小結:

鏈表是以節點的方式來存儲,是鏈式存儲

每個節點包含 data 域, next 域:指向下一個節點.

如圖:發現鏈表的各個節點不一定是連續存儲.

鏈表分帶頭節點的鏈表和沒有頭節點的鏈表,根據實際的需求來確定

結合一個實際的工作案例, 說明鏈表的實用價值

單鏈表

單鏈表(帶頭結點) 邏輯結構示意圖如下

img

嗶哩嗶哩動畫

單鏈表的應用實例

使用帶head頭的單向鏈表實現 –水滸英雄排行榜管理 完成對英雄人物的增刪改查操作, 注: 刪除和修改,查找可以考慮學員獨立完成,也可帶學員完成 第一種方法在添加英雄時,直接添加到鏈表的尾部 第二種方式在添加英雄時,根據排名將英雄插入到指定位置(如果有這個排名,則添加失敗,并給出提示)

img

單鏈表的常見面試題有如下:

求單鏈表中有效節點的個數

查找單鏈表中的倒數第k個結點 【新浪面試題】

單鏈表的反轉【騰訊面試題,有點難度】

從尾到頭打印單鏈表 【百度,要求方式1:反向遍歷 。 方式2:Stack棧】

合并兩個有序的單鏈表,合并之后的鏈表依然有序【課后練習.】

直接看老師代碼演示 。

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. 如果找到了,則返回該節點,否則返回nulllpublic static HeroNode findLastIndexNode(HeroNode head, int index) {//判斷如果鏈表為空,返回nullif(head.next == null) {return null;//沒有找到}//第一個遍歷得到鏈表的長度(節點個數)int size = getLength(head);//第二次遍歷  size-index 位置,就是我們倒數的第K個節點//先做一個index的校驗if(index <=0 || index > size) {return null; }//定義給輔助變量, for 循環定位到倒數的indexHeroNode cur = head.next; //3 // 3 - 1 = 2for(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節點不能動,因此我們需要一個輔助遍歷 tempHeroNode 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標志添加的編號是否存在,默認為falsewhile(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) {//找到的待刪除節點的前一個節點tempflag = true;break;}temp = temp.next; //temp后移,遍歷}//判斷flagif(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@Overridepublic String toString() {return "HeroNode [no=" + no + ", name=" + name + ", nickname=" + nickname + "]";}}

運行結果

原來鏈表的情況~~
HeroNode [no=1, name=宋江, nickname=及時雨]
HeroNode [no=4, name=林沖, nickname=豹子頭]
HeroNode [no=2, name=盧俊義, nickname=玉麒麟]
HeroNode [no=3, name=吳用, nickname=智多星]
測試逆序打印單鏈表, 沒有改變鏈表的結構~~
HeroNode [no=3, name=吳用, nickname=智多星]
HeroNode [no=2, name=盧俊義, nickname=玉麒麟]
HeroNode [no=4, name=林沖, nickname=豹子頭]
HeroNode [no=1, name=宋江, nickname=及時雨]Process finished with exit code 0

原文地址:傳送門

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/455108.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/455108.shtml
英文地址,請注明出處:http://en.pswp.cn/news/455108.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

有字符csv文件導入matlab_Matlab:如何讀取CSV文件以及如何讀取帶有字符串數據項的CSV文件...

CSV&#xff0c;逗號分開的文件&#xff0c;如果能快速的讀取這些文件中的數據&#xff0c;無疑會幫助我們解決很多問題。1、 只有數據的CSV文件&#xff0c;CSV file that includes only numbers.As an example, create a text file, named as data.csv if you prefer, which …

xchg_mb_border()

顧名思義&#xff0c; xchg_mb_border() 交換 MB 邊界的像素。閱讀代碼可知&#xff0c;交換雙方為邊界緩存 (left_border,top_borders) 與重建圖象中的相應數據。其中 xchg 參數是否為 1 決定&#xff0c;在從邊界緩存賦值到重建圖象的同時&#xff0c;是否保存重建圖象的數據…

Introduction to the Optimizer --cbo

http://docs.oracle.com/cd/B10500_01/server.920/a96533/optimops.htm

統計字符串中某個字出現的次數

package ch11;import java.util.Scanner;/** * Created by liwenj on 2017/7/21. */public class T6 { public static void main(String[] args) { String w "我愛你中國&#xff0c;我愛你故鄉"; String a "愛"; int k0; …

jedispool redis哨兵_通過java哨兵JedisSentinelPool代碼示例連接對配置的redis哨兵主從模式進行測試驗證...

一、前言本文章通過關于java的jedis(2.6.0)的redis客戶端連接驅動包&#xff0c;對配置的redis哨兵主從讀寫模式配置進行示例代碼驗證&#xff0c;詳細參見具體配置步驟&示例代碼說明部分。二、配置步驟1. 安裝redis(參考其他文章教程),并配置主從模式(參考其他相關文章&am…

鏈表(Linked List)之雙向鏈表

雙向鏈表應用實例 使用帶head頭的雙向鏈表實現 –水滸英雄排行榜 管理單向鏈表的缺點分析: 單向鏈表&#xff0c;查找的方向只能是一個方向&#xff0c;而雙向鏈表可以向前或者向后查找。 單向鏈表不能自我刪除&#xff0c;需要靠輔助節點 &#xff0c;而雙向鏈表&#xff…

H264 解碼耗時分析

在數字基帶處理器上代碼的最佳放置 美國模擬器件公司 Jose Fridman   在手機等嵌入式系統中&#xff0c;除了處理器執行時間外&#xff0c;最重要的資源就是設備總線和存儲器接口。本文將介紹一種在使用指令高速緩存時其帶寬消耗的基礎上&#xff0c;統計分析高速緩存所采用…

CentOS 7 使用iptables防火墻

# 停止firewalld服務 systemctl stop firewalld systemctl mask firewalld # 安裝iptables-services yum install iptables-services Enable the service at boot-time: # 啟動iptables服務 systemctl enable iptables # 管理iptables systemctl [stop|start|restart] ip…

Linux命令之useradd和userdel(添加、刪除用戶)

一、【useradd】&#xff1a;添加用戶命令 1.作用useradd或adduser命令用來建立用戶帳號和創建用戶的起始目錄&#xff0c;使用權限是超級用戶。 2.格式 useradd [-d home] [-s shell] [-c comment] [-m [-k template]] [-f inactive] [-e expire ] [-p passwd] [-r] name 3.主…

鏈表(Linked List)之環形鏈表

原文地址:傳送門 單向環形鏈表應用場景 Josephu(約瑟夫、約瑟夫環) 問題 Josephu 問題為&#xff1a;設編號為1&#xff0c;2&#xff0c;… n的n個人圍坐一圈&#xff0c;約定編號為k&#xff08;1<k<n&#xff09;的人從1開始報數&#xff0c;數到m 的那個人出列&…

springboot 單測加入參數_spring-boot-單元測試參數數

簡單案例RunWith(Parameterized.class)public class ParameterTest {// 2.聲明變量存放預期值和測試數據private String firstName;private String lastName;//3.聲明一個返回值 為Collection的公共靜態方法&#xff0c;并使用Parameters進行修飾Parameterized.Parameterspubli…

H.264/AVC 標準中CAVLC 和CABAC 熵編碼算法研究

http://www.paper.edu.cn/index.php/default/releasepaper/downPaper/200903-146

python ==》 元組

為何要有元組 &#xff0c;() 可存放多個值 元組不可變 更多的是用來查詢t (1,[1,3],sss,(1,2)) #t tuple(1,[1,3],sss,(1,2))print (type(t))元組可以作為字典的keyd{(1,2,3):zcx}print(d,type(d),d[(1,2,3)])索引取值d (1,2,3,4,5)print(d[1])切片goods (iphone,lenove,…

免費SSL證書(支持1.0、1.1、1.2)

由于公司要開發微信小程序&#xff0c;而微信小程序的接口需要https協議的&#xff0c;并且要支持TLS1.0、TLS1.1、TLS1.2。如果僅僅是為了開發小程序&#xff0c;安全等級又不用太高&#xff0c;可以選擇免費的SSL證書 在這里選擇騰訊云的證書&#xff0c;申請在 https://cons…

viewsource和viewparsed_Network Panel說明

一、chrome Developer Tools&#xff1a;Network Panel從網絡面板中可以獲取很多有用信息&#xff0c;如詳細的時間數據&#xff0c;http請求頭響應頭&#xff0c;cookies&#xff0c;WebSocket數據。通過分析這些數據&#xff0c;可以知道哪個資源加載耗時最久&#xff0c;誰發…

使用棧來完成一個表達式的結果

原文地址:傳送門 使用棧來完成一個表達式的結果 使用棧完成計算 一個表達式的結果 7*2*2-51-53-4 &#xff1f; 32*6-2[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-XzPnJzRe-1614845779689)(https://victorfengming.gitee.io/data_algorithm/i…

JM與h264標準中的關鍵字說明

有些亂&#xff0c;先存著&#xff0c;留著看 如何結合H.264標準看JM代碼》這個web文件&#xff0c;大家都應該有了吧。不過&#xff0c;那個web文檔是“H.264樂園”群中聊天的內容 1、一個sps后&#xff0c;有若干個pps嗎&#xff1f; 這主要又編碼器決定&#xff0c;但J…

云計算(cloud computing)十大問答

本文講的是云計算&#xff08;cloud computing&#xff09;十大問答&#xff0c;【IT168 資訊】云計算這個新名詞最近甚囂塵上&#xff0c;最近周圍不少朋友都在談&#xff0c;有必要寫一個關于云計算的科普了。  一般的業界比較喜歡用一些新名詞來體現 自己的戰略眼光和與對…

3150cdn打印機清零 hl_兄弟HL-3150/3140彩色打印機粉盒清零方法,我們提前了解一下...

原標題&#xff1a;兄弟HL-3150/3140彩色打印機粉盒清零方法&#xff0c;我們提前了解一下對于兄弟品牌的打印機&#xff0c;相信各位經銷商朋友都遇到過&#xff0c;更換新的粉盒或者加粉后還會提示墨粉不足、更換碳粉盒、更換硒鼓。這個情況需要在機器上操作清零&#xff01;…

Python 關于bytes類方法對數字轉換的誤區, Json的重要性

本文起源于一次犯錯, 在發覺bytes()里面可以填數字, 轉出來的也是bytes類型, 就心急把里面的東西decode出來. 結果為空.搞來搞去以為是命令不熟練事實上錯在邏輯.a1 bytes(11, encodingutf-8) print(a1)b1 a1.decode()print(b1)a2 bytes(11) print(a2)b2 a2.decode() print…