Java語(yǔ)言之LinkedList和鏈表的實(shí)現(xiàn)方法
一.鏈表概念
鏈表是一種物理存儲(chǔ)結(jié)構(gòu)上非連續(xù)存儲(chǔ)結(jié)構(gòu),數(shù)據(jù)元素的邏輯順序是通過(guò)鏈表中的引用鏈接次序?qū)崿F(xiàn)的 。
邏輯結(jié)構(gòu):

注:1、如上圖,相當(dāng)于火車(chē)車(chē)廂,每一節(jié)都相連在一起。
2、各個(gè)結(jié)點(diǎn)連接的方式:通過(guò)地址連接,在內(nèi)存當(dāng)中,相鄰結(jié)點(diǎn)在內(nèi)存中不一定相鄰。
3、所有結(jié)點(diǎn)都在 堆 中申請(qǐng)出來(lái)。
4、 每個(gè)結(jié)點(diǎn)包括兩個(gè)部分:一個(gè)是存儲(chǔ)數(shù)據(jù)元素的數(shù)據(jù)域,另一個(gè)是存儲(chǔ)下一個(gè)結(jié)點(diǎn)地址的指針域。
二.鏈表的分類(lèi)
1.單向、雙向鏈表

注:無(wú)論單向還是雙向,都是一個(gè)結(jié)點(diǎn)存儲(chǔ)著下(上)一個(gè)結(jié)點(diǎn)。
2.帶頭、不帶頭結(jié)點(diǎn) 鏈表

注:無(wú)頭和帶頭結(jié)點(diǎn)的主要區(qū)別:有一個(gè)起始結(jié)點(diǎn)。
3.循環(huán)、非循環(huán)鏈表

循環(huán)鏈表,就是指:頭、尾結(jié)點(diǎn)有聯(lián)系。
在鏈表結(jié)構(gòu)中,這是主要的鏈表,但是這些鏈表種類(lèi)還可以結(jié)合,如:帶頭雙向循環(huán)鏈表、雙向循環(huán)鏈表等等。
鏈表的種類(lèi)很多,但都大同小異,我們主要學(xué)習(xí)兩種鏈表:
1、無(wú)頭單向非循環(huán)鏈表:結(jié)構(gòu)簡(jiǎn)單,一般不會(huì)單獨(dú)用來(lái)存數(shù)據(jù)。實(shí)際中更多是作為其他數(shù)據(jù)結(jié)構(gòu)的子結(jié)構(gòu),如哈希桶、圖的鄰接表等等。另外這種結(jié)構(gòu)在筆試面試中出現(xiàn)很多。
2、無(wú)頭雙向鏈表:在Java的集合框架庫(kù)中LinkedList底層實(shí)現(xiàn)就是無(wú)頭雙向循環(huán)鏈表
三.無(wú)頭單向非循環(huán)鏈表的實(shí)現(xiàn)
3.1創(chuàng)建簡(jiǎn)單鏈表

重點(diǎn):每個(gè)結(jié)點(diǎn)存儲(chǔ)著下一個(gè)結(jié)點(diǎn)的地址。
創(chuàng)建鏈表代碼實(shí)現(xiàn):
public class SingleLinkedList {
static class List{
int item; // 存儲(chǔ)數(shù)據(jù)
List next; // 指向下一個(gè)結(jié)點(diǎn)
public List(int item) {
this.item = item;
}
public List() {};
}
//各種鏈表實(shí)現(xiàn)方法
//頭插法
public void addFirst(int data){
}
//尾插法
public void addLast(int data){
}
//任意位置插入,第一個(gè)數(shù)據(jù)節(jié)點(diǎn)為0號(hào)下標(biāo)
public void addIndex(int index,int data){
}
//查找是否包含關(guān)鍵字key是否在單鏈表當(dāng)中
public boolean contains(int key){
return false;
}
//刪除第一次出現(xiàn)關(guān)鍵字為key的節(jié)點(diǎn)
public void remove(int key){
}
//得到單鏈表的長(zhǎng)度
public int size(){
return -1;
}
//鏈表的清空
public void clear() {
}
//展示鏈表
public void display() {}3.2 鏈表基本方法實(shí)現(xiàn)
1.遍歷鏈表元素
public void show() {
//這里不是定義了一個(gè)節(jié)點(diǎn) 這里只是一個(gè)引用
ListNode cur = head;
while (cur != null) {
System.out.print(cur.val+" ");
cur = cur.next;
}
System.out.println();
}2.獲取鏈表長(zhǎng)度
public int size(){
int count = 0;
ListNode cur = head;
while (cur != null) {
count++;
cur = cur.next;
}
return count;
}3.查詢(xún)數(shù)據(jù)
public boolean contains(int key){
ListNode cur = head;
while (cur != null) {
//如果val值 是引用類(lèi)型 那么這里得用equals來(lái)進(jìn)行比較!??!
if(cur.val == key) {
return true;
}
cur = cur.next;
}
return false;
}4.鏈表的清空
public void clear() {
//將所有結(jié)點(diǎn)都置空,更為安全
while (head != null) {
ListNode headNext = head.next;
head.next = null;
head = headNext;
}
}3.3四大基本功能
3.3.1 、增加元素結(jié)點(diǎn)
1.頭插法:將新增結(jié)點(diǎn)放在鏈表的頭部。
public void addFirst(int data){
ListNode node = new ListNode(data);
node.next = head;
head = node;
}2.尾插法:將新增結(jié)點(diǎn)直接連接在鏈表的尾部
public void addLast(int data){
ListNode node = new ListNode(data);
if(head == null) {
head = node;
return;
}
ListNode cur = head;
while (cur.next != null) {
cur = cur.next;
}
//cur 指向的節(jié)點(diǎn)就是尾巴節(jié)點(diǎn)
cur.next = node;
}3.選擇下標(biāo)值,添加結(jié)點(diǎn)
public void addIndex(int index,int data){
int len = size();
//0、判斷index位置的合法性
if(index < 0 || index > len) {
throw new IndexOutOfBounds("任意位置插入數(shù)據(jù)的時(shí)候,index位置不合法: "+index);
}
if(index == 0) {
addFirst(data);
return;
}
if(index == len) {
addLast(data);
return;
}
//1、先找到index-1位置的節(jié)點(diǎn)
ListNode cur = findIndex(index);
//2、進(jìn)行插入
ListNode node = new ListNode(data);
node.next = cur.next;
cur.next = node;
}3.3.2.查找元素結(jié)點(diǎn)
查找一個(gè)元素,返回對(duì)應(yīng)的下標(biāo)值。
public ListNode findIndex(int index) {
ListNode cur = head;
while (index - 1 != 0) {
cur = cur.next;
index--;
}
return cur;//index-1位置的節(jié)點(diǎn)
}3.3.3.刪除元素結(jié)點(diǎn)
先找到對(duì)應(yīng)的下標(biāo)值,然后進(jìn)行刪除。刪除方法,前一個(gè)結(jié)點(diǎn)連接到刪除結(jié)點(diǎn)的后一個(gè)結(jié)點(diǎn)。

如圖,先斷開(kāi)d2與d3的連接,然后d2直接連接d4
代碼實(shí)現(xiàn):
//刪除第一次出現(xiàn)關(guān)鍵字為key的節(jié)點(diǎn)
public void remove(int key){
if(head == null) {
return;
}
//當(dāng)刪除結(jié)點(diǎn)為頭結(jié)點(diǎn)
if(head.val == key) {
head = head.next;
return;
}
ListNode prev = searchPrev(key); //返回待刪除結(jié)點(diǎn)的前一個(gè)結(jié)點(diǎn)
if(prev == null) {
System.out.println("沒(méi)有這個(gè)數(shù)據(jù)!");
return;
}
ListNode del = prev.next;
prev.next = del.next;
}
private ListNode searchPrev(int key) {
ListNode prev = head;
while (prev.next != null) {
if(prev.next.val == key) {
return prev;
}else {
prev = prev.next;
}
}
return null;
}3.3.4.結(jié)點(diǎn)信息修改
修改指定下標(biāo)值的結(jié)點(diǎn)元素
public void searchPrev(int num,int date) {
ListNode prev = head;
for(int i=0;i<num-1;i++) {
prev = prev.next;
}
prev.val=date;
}四.LinkedList是什么?
LinkedList的底層是雙向鏈表結(jié)構(gòu),由于鏈表沒(méi)有將元素存儲(chǔ)在連續(xù)的空間中,元素存儲(chǔ)在單獨(dú)的節(jié)點(diǎn)中,然后通過(guò)引用將節(jié)點(diǎn)連接起來(lái)了,因此在在任意位置插入或者刪除元素時(shí),不需要搬移元素,效率比較高。

如圖所示:1. LinkedList實(shí)現(xiàn)了List接口
2. LinkedList的底層使用了雙向鏈表
3. LinkedList沒(méi)有實(shí)現(xiàn)RandomAccess接口,因此LinkedList不支持隨機(jī)訪問(wèn)。
4. LinkedList的任意位置插入和刪除元素時(shí)效率比較高,時(shí)間復(fù)雜度為O(1)
5. LinkedList比較適合任意位置插入的場(chǎng)景
五.LinkedList使用方法
| 方法 | 解釋 | |
| 構(gòu)造方法 | LinkedList() | 無(wú)參構(gòu)造 |
| public LinkedList(Collection<? extends E> c) | 使用其他集合容器中元素構(gòu)造List | |
| 常用方法 | boolean add(E e) | 尾插e(cuò) |
| void add(int index,E element) | 將e插入到index位置 | |
| boolean addAII(Collection<? extends E> c) | 尾插c中的元素 | |
| E remove(int index) | 刪除index位置元素 | |
| boolean remove(Object o) | 刪除遇到的第一個(gè)o | |
| E get( int index) | 獲取下標(biāo)index位置元素 | |
| void clear() | 清空 |
總結(jié)
到此這篇關(guān)于Java語(yǔ)言之LinkedList和鏈表的實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)Java LinkedList和鏈表實(shí)現(xiàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Web三大組件之Filter,Listener和Servlet詳解
這篇文章主要為大家詳細(xì)介紹了Web三大組件之Filter,Listener和Servlet,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-03-03
IDEA2022版本創(chuàng)建maven?web項(xiàng)目的兩種方式詳解
創(chuàng)建maven?web項(xiàng)目有兩種方式,一種是使用骨架方式,一種是不使用骨架的方式,本文結(jié)合實(shí)例代碼給大家介紹了IDEA2022版本創(chuàng)建maven?web項(xiàng)目的兩種方式,需要的朋友可以參考下2023-02-02
利用spring boot如何快速啟動(dòng)一個(gè)web項(xiàng)目詳解
這篇文章主要給大家介紹了關(guān)于利用spring boot如何快速啟動(dòng)一個(gè)web項(xiàng)目的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧、2017-12-12
AbstractQueuedSynchronizer內(nèi)部類(lèi)Node使用講解
這篇文章主要為大家介紹了AbstractQueuedSynchronizer內(nèi)部類(lèi)Node使用講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
Spring Boot集成Druid數(shù)據(jù)庫(kù)連接池
這篇文章主要介紹了Spring Boot集成Druid數(shù)據(jù)庫(kù)連接池,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04
spring?boot集成smart-doc自動(dòng)生成接口文檔詳解
這篇文章主要介紹了spring?boot集成smart-doc自動(dòng)生成接口文檔詳解,smart-doc是一款同時(shí)支持java?restful?api和Apache?Dubbo?rpc接口文檔生成的工具,smart-doc顛覆了傳統(tǒng)類(lèi)似swagger這種大量采用注解侵入來(lái)生成文檔的實(shí)現(xiàn)方法2022-09-09
Java 改造ayui表格組件實(shí)現(xiàn)多重排序
layui 的表格組件目前只支持單列排序,在實(shí)際應(yīng)用中并不能很好的支撐我們的業(yè)務(wù)需求。今天一時(shí)手癢,決定改造一番以支持多重排序。2021-04-04

