java鏈表實現_鏈表的原理及java實現

一:單向鏈表基本介紹

鏈表是一種數據結構,和數組同級。比如,Java中我們使用的ArrayList,其實現原理是數組。而LinkedList的實現原理就是鏈表了。鏈表在進行循環遍歷時效率不高,但是插入和刪除時優勢明顯。下面對單向鏈表做一個介紹。

單向鏈表是一種線性表,實際上是由節點(Node)組成的,一個鏈表擁有不定數量的節點。其數據在內存中存儲是不連續的,它存儲的數據分散在內存中,每個結點只能也只有它能知道下一個結點的存儲位置。由N各節點(Node)組成單向鏈表,每一個Node記錄本Node的數據及下一個Node。向外暴露的只有一個頭節點(Head),我們對鏈表的所有操作,都是直接或者間接地通過其頭節點來進行的。

7fe5e321f23ca6d19c4a5821bc5c2523.png?

上圖中最左邊的節點即為頭結點(Head),但是添加節點的順序是從右向左的,添加的新節點會被作為新節點。最先添加的節點對下一節點的引用可以為空。引用是引用下一個節點而非下一個節點的對象。因為有著不斷的引用,所以頭節點就可以操作所有節點了。

下圖描述了單向鏈表存儲情況。存儲是分散的,每一個節點只要記錄下一節點,就把所有數據串了起來,形成了一個單向鏈表。

efd7e171d0de3af3b256b1cc6f8d7b1b.png?

節點(Node)是由一個需要儲存的對象及對下一個節點的引用組成的。也就是說,節點擁有兩個成員:儲存的對象、對下一個節點的引用。下面圖是具體的說明:

e4f112fae7021bb23bd950af121438fe.png

二、單項鏈表的實現

/***@authorAdministrator*/

public classMyLink {

Node head= null; //頭節點

/*** 鏈表中的節點,data代表節點的值,next是指向下一個節點的引用

*

*@authorzjn

**/

classNode {

Node next= null;//節點的引用,指向下一個節點

int data;//節點的對象,即內容

public Node(intdata) {this.data =data;

}

}/*** 向鏈表中插入數據

*

*@paramd*/

public void addNode(intd) {

Node newNode= new Node(d);//實例化一個節點

if (head == null) {

head=newNode;return;

}

Node tmp=head;while (tmp.next != null) {

tmp=tmp.next;

}

tmp.next=newNode;

}/***

*@paramindex:刪除第index個節點

*@return

*/

public boolean deleteNode(intindex) {if (index < 1 || index >length()) {return false;

}if (index == 1) {

head=head.next;return true;

}int i = 1;

Node preNode=head;

Node curNode=preNode.next;while (curNode != null) {if (i ==index) {

preNode.next=curNode.next;return true;

}

preNode=curNode;

curNode=curNode.next;

i++;

}return false;

}/***

*@return返回節點長度*/

public intlength() {int length = 0;

Node tmp=head;while (tmp != null) {

length++;

tmp=tmp.next;

}returnlength;

}/*** 在不知道頭指針的情況下刪除指定節點

*

*@paramn

*@return

*/

public booleandeleteNode11(Node n) {if (n == null || n.next == null) {return false;

}int tmp =n.data;

n.data=n.next.data;

n.next.data=tmp;

n.next=n.next.next;

System.out.println("刪除成功!");return true;

}public voidprintList() {

Node tmp=head;while (tmp != null) {

System.out.println(tmp.data);

tmp=tmp.next;

}

}public static voidmain(String[] args) {

MyLink list= newMyLink();

list.addNode(5);

list.addNode(3);

list.addNode(1);

list.addNode(2);

list.addNode(55);

list.addNode(36);

System.out.println("linkLength:" +list.length());

System.out.println("head.data:" +list.head.data);

list.printList();

list.deleteNode(4);

System.out.println("After deleteNode(4):");

list.printList();

}

}

三、鏈表相關的常用操作實現方法

1. 鏈表反轉

/*** 鏈表反轉

*

*@paramhead

*@return

*/

publicNode ReverseIteratively(Node head) {

Node pReversedHead=head;

Node pNode=head;

Node pPrev= null;while (pNode != null) {

Node pNext=pNode.next;if (pNext == null) {

pReversedHead=pNode;

}

pNode.next=pPrev;

pPrev=pNode;

pNode=pNext;

}this.head =pReversedHead;return this.head;

}

2. 查找單鏈表的中間節點

采用快慢指針的方式查找單鏈表的中間節點,快指針一次走兩步,慢指針一次走一步,當快指針走完時,慢指針剛好到達中間節點。

/*** 查找單鏈表的中間節點

*

*@paramhead

*@return

*/

publicNode SearchMid(Node head) {

Node p= this.head, q = this.head;while (p != null && p.next != null && p.next.next != null) {

p=p.next.next;

q=q.next;

}

System.out.println("Mid:" +q.data);returnq;

}

3. 查找倒數第k個元素

采用兩個指針P1,P2,P1先前移K步,然后P1、P2同時移動,當p1移動到尾部時,P2所指位置的元素即倒數第k個元素 。

/*** 查找倒數 第k個元素

*

*@paramhead

*@paramk

*@return

*/

public Node findElem(Node head, intk) {if (k < 1 || k > this.length()) {return null;

}

Node p1=head;

Node p2=head;for (int i = 0; i < k; i++)//前移k步

p1 =p1.next;while (p1 != null) {

p1=p1.next;

p2=p2.next;

}returnp2;

}

4. 對鏈表進行排序

/*** 排序

*

*@return

*/

publicNode orderList() {

Node nextNode= null;int tmp = 0;

Node curNode=head;while (curNode.next != null) {

nextNode=curNode.next;while (nextNode != null) {if (curNode.data >nextNode.data) {

tmp=curNode.data;

curNode.data=nextNode.data;

nextNode.data=tmp;

}

nextNode=nextNode.next;

}

curNode=curNode.next;

}returnhead;

}

5. 刪除鏈表中的重復節點

/*** 刪除重復節點*/

public voiddeleteDuplecate(Node head) {

Node p=head;while (p != null) {

Node q=p;while (q.next != null) {if (p.data ==q.next.data) {

q.next=q.next.next;

}elseq=q.next;

}

p=p.next;

}

}

6. 從尾到頭輸出單鏈表,采用遞歸方式實現

/*** 從尾到頭輸出單鏈表,采用遞歸方式實現

*

*@parampListHead*/

public voidprintListReversely(Node pListHead) {if (pListHead != null) {

printListReversely(pListHead.next);

System.out.println("printListReversely:" +pListHead.data);

}

}

7. 判斷鏈表是否有環,有環情況下找出環的入口節點

/*** 判斷鏈表是否有環,單向鏈表有環時,尾節點相同

*

*@paramhead

*@return

*/

public booleanIsLoop(Node head) {

Node fast= head, slow =head;if (fast == null) {return false;

}while (fast != null && fast.next != null) {

fast=fast.next.next;

slow=slow.next;if (fast ==slow) {

System.out.println("該鏈表有環");return true;

}

}return !(fast == null || fast.next == null);

}/*** 找出鏈表環的入口

*

*@paramhead

*@return

*/

publicNode FindLoopPort(Node head) {

Node fast= head, slow =head;while (fast != null && fast.next != null) {

slow=slow.next;

fast=fast.next.next;if (slow ==fast)break;

}if (fast == null || fast.next == null)return null;

slow=head;while (slow !=fast) {

slow=slow.next;

fast=fast.next;

}returnslow;

}

轉載自:https://blog.csdn.net/jianyuerensheng/article/details/51200274

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

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

相關文章

python和django中的常見錯誤

int() argument must be a string or a number, not tupleError in formatting: coercing to Unicode: need string or buffer, int foundData truncated for column content at row 1sql語句中單引號的設置字段類型字段長度 ascii codec cant decode byte 0xe7 in position 0:…

20141126-解決聯網問題-筆記

當你的網絡出現故障或無法連通時&#xff0c;如何才能簡單高效的找出故障&#xff1f;其實只需要一個ping命令&#xff0c;就可以判斷TCP/IP協議故障…… 1、Ping 127.0.0.1&#xff1a; 127.0.0.1是本地循環地址&#xff0c;如果本地址無法Ping通&#xff0c;則表明本地機TCP/…

inittab腳本啟動解析 (zz)

http://blog.chinaunix.net/uid-17188120-id-4073497.html 1&#xff0c;啟動inittab第一步&#xff1a;啟動內核第二步&#xff1a;執行init &#xff08;配置文件/etc/inittab&#xff09;第三步&#xff1a;啟動相應的腳本&#xff0c;執行inittab腳本&#xff0c;并且執行其…

java緩存技術_java緩存技術

最近在做java緩存,了解了一下.以下僅是對map對方式討論。沒有對點陣圖陣討論。作緩存要做以下2點:1:清理及更新緩存時機的處理:. 虛擬機內存不足,清理緩存.. 緩存時間超時,或訪問次數超出, 啟動線程更新2:類和方法的反射 (線程嵌套調用)reflect.invoke的使用。代碼如下&#xf…

xss challenge 解題思路(1-3)

challenge1: 用很基本的方法即可&#xff0c;截圖如下&#xff1a; 提交后成功彈窗&#xff0c;完成。 challenge2 這次我們發現我們輸入的內容被放入value”“ 中&#xff0c;所以需要將前面的結構閉合&#xff0c;構造如下&#xff1a; "><script>alert(docume…

賓得準餅干廣角鏡頭DA15

DA15的掛機效果圖&#xff0c;感覺還是超級的小&#xff0c;是最小的廣角鏡頭了&#xff1a; 主要特點1. 超廣視角當安裝在賓得數碼單反相機上時&#xff0c;這款全新的鏡頭提供相當于35mm膠片規格的約23mm畫面視角&#xff0c;可使拍攝者拍攝出獨特的誘人影像和超廣角鏡頭獨有…

無限“遞歸”的python程序

如果一個函數直接或者間接調用了自己&#xff0c;那么就形成了遞歸&#xff08;recursion&#xff09;&#xff0c;比如斐波那契數列的一個實現 def fib(n):if n < 2:return 1else:return fib(n - 1) fib(n - 2) 遞歸一定要有結束條件&#xff0c;否則就形成了死循環&#…

java slf4j_SLF4J 使用手冊

原文鏈接 譯者&#xff1a;zivyuJava的簡單日志門面( Simple Logging Facade for Java SLF4J)作為一個簡單的門面或抽象&#xff0c;用來服務于各種各樣的日志框架&#xff0c;比如java.util.logging、logback和log4j。SLF4J允許最終用戶在部署時集成自己想要的日志框架。需要…

[譯]Java 垃圾回收介紹

說明&#xff1a;這篇文章來翻譯來自于Javapapers 的Java Garbage Collection Introduction 在Java中&#xff0c;對象內存空間的分配與回收是由JVM中的垃圾回收進程自動完成的。和C語言不一樣的是&#xff0c;開發中不需要在Java中寫垃圾回收代碼。這也是使Java更加流行而且幫…

打印三角形

直角三角形 #include<iostream> using namespace std; int main() { int i,j; for(i1;i<10;i) {for(j1;j<i;j) cout<<"*"; cout<<endl; } } ———————————————————————————…

Linux基礎入門學習筆記之二

第三節 用戶及文件權限管理 Linux用戶管理 Linux是可以實現多用戶登錄的操作系統 查看用戶who命令用于查看用戶 shiyanlou是當前登錄用戶的用戶名 pts/0中pts表示偽終端&#xff0c;后面的數字表示偽終端的序號。 后面是當前偽終端啟動時間 創建用戶創建用戶需要root權限&#…

java選填_java基礎填空選擇題

Core Java試題選擇填空題&#xff1a;全部為多選題&#xff0c;只有全部正確才能得分。1. 編譯java程序的命令是__B_;運行java程序的命令是____A____;產生java文擋的命令是_____D___;查詢java類型是否是serializable類型的命令是___C_____;產生java安全策略文件的命令是____E__…

這幾天有django和python做了一個多用戶博客系統(可選擇模板) 沒完成,先分享下...

這個TBlog已經全新改版了&#xff0c;更名為UUBlog 新版地址&#xff1a; 用Python和Django實現多用戶博客系統——UUBlog 斷斷續續2周時間吧&#xff0c;用django做了一個多用戶博客系統&#xff0c;現在還沒有做完&#xff0c;做分享下,以后等完善了再慢慢說 做的時候房展了博…

Hibernate的generator屬性

本文講述Hibernate的generator屬性的意義。Generator屬性有7種class&#xff0c;本文簡略描述了這7種class的意義和用法。[xhtml] view plaincopy <class name"onlyfun.caterpillar.User" table"USER"> <id name"id" type"stri…

java 對象池 博客_Java對象池技術的原理及其實現的小結

一起學習Java對象的生命周期大致包括三個階段&#xff1a;對象的創建&#xff0c;對象的使用&#xff0c;對象的清除。因此&#xff0c;對象的生命周期長度可用如下的表達式表示&#xff1a;T T1 T2 T3。其中T1表示對象的創建時間&#xff0c;T2表示對象的使用時間&#xff0c…

matlab中gatbx工具箱的添加

1. 從http://crystalgate.shef.ac.uk/code/下載工具箱壓縮包gatbx.zip 2. 解壓gatbx.zip&#xff0c;將其子文件夾genetic放在matlab安裝目錄toolbox文件夾下 3. 在matlab主窗口選擇File -> Set Path&#xff0c; 單擊"Add Folder"按鈕&#xff0c;找到工具箱所在…

C#與數據庫訪問技術總結(十七)

使用DataSet對象訪問數據庫 當對DataSet對象進行操作時&#xff0c;DataSet對象會產生副本&#xff0c;所以對DataSet里的數據進行編輯操作不會直接對數據庫產生影響&#xff0c;而是將DataRow的狀態設置為added、deleted或changed&#xff0c;最終的更新數據源動作將通過DataA…

MySQL數據高級查詢之連接查詢、聯合查詢、子查詢

2019獨角獸企業重金招聘Python工程師標準>>> 一、連接查詢 連接查詢: 將多張表(>2)進行記錄的連接(按照某個指定的條件進行數據拼接)。 連接查詢的意義: 在用戶查看數據的時候,需要顯示的數據來自多張表. 連接查詢: join, 使用方式: 左表 join 右表&#xff1b;左…

Oracle11g解鎖報錯SP2-0306-選項無效

普通用戶登錄isqlplus: (一)在瀏覽器中輸入URL &#xff08;http://localhost:5560/isqlplus&#xff09;。顯示登錄界面 這里只能用普通用戶進行登錄&#xff0c;因為要用sys登錄&#xff0c;必須用sys的DBA身份登錄。所以用普通用戶SCOTT&#xff0c;但是還未解鎖 問題:SP2-0…

java web登錄action_JavaWeb中登陸功能

首先我們要JavaWeb登陸的基本流程&#xff1a;JSP頁面發送請求——>Servlet——>Servlet通過調用方法從數據庫中得到數據并將結果返回頁面我們先建立三個jsp頁面&#xff0c;包括login.jsp(登陸頁面)、index.jsp(顯示登陸成功后的信息)、error.jsp(登錄失敗的頁面)&#…