Java?精煉解讀數(shù)據(jù)結(jié)構(gòu)的鏈表的概念與實(shí)現(xiàn)
前言:
順序表的問題及思考
1. 順序表中間/頭部的插入刪除,時(shí)間復(fù)雜度為O(N)
2. 增容需要申請(qǐng)新空間,拷貝數(shù)據(jù),釋放舊空間。會(huì)有不小的消耗。
3. 增容一般是呈2倍的增長(zhǎng),勢(shì)必會(huì)有一定的空間浪費(fèi)。例如當(dāng)前容量為100,滿了以后增容到200,我們?cè)倮^續(xù) 插入了5個(gè)數(shù)據(jù),后面沒有數(shù)據(jù)插入了,那么就浪費(fèi)了95個(gè)數(shù)據(jù)空間。
思考: 如何解決以上問題呢?下面給出了鏈表的結(jié)構(gòu)來看看。
一、什么是鏈表
鏈表的概念
鏈表是一種物理存儲(chǔ)結(jié)構(gòu)上非連續(xù)存儲(chǔ)結(jié)構(gòu),數(shù)據(jù)元素的邏輯順序是通過鏈表中的引用鏈接次序?qū)崿F(xiàn)的 。
鏈表的結(jié)構(gòu)
鏈表結(jié)構(gòu)分為8種:

這里我們只講最下面兩種,因?yàn)樵诠ぷ髦?、業(yè)務(wù)里、考試題、刷到的鏈表題、面試題里面都是用到這兩種鏈表。?
鏈表如何存儲(chǔ)數(shù)據(jù)
鏈表是由一個(gè)一個(gè)節(jié)點(diǎn)組成的。(這里我們以單鏈表為例)
什么叫做節(jié)點(diǎn)?
節(jié)點(diǎn)分為兩個(gè)域 ,假設(shè)一個(gè)叫做val域,一個(gè)叫做next域。
val:數(shù)據(jù)域
next:下一個(gè)節(jié)點(diǎn)的地址

鏈表的實(shí)現(xiàn)??
//ListNode代表一個(gè)節(jié)點(diǎn)
class ListNode{
public int val;
public ListNode next;
//構(gòu)造方法
public ListNode(int val){
this.val = val;
}
}
//MyLinkedList 代表這是一個(gè)鏈表
public class MyLinkedList {
public ListNode head;//鏈表的頭引用,所以定義在鏈表里,head是鏈表的頭,不是節(jié)點(diǎn)的頭,節(jié)點(diǎn)只有兩個(gè)屬性,一個(gè)屬性是val值,一個(gè)屬性是next值,所以不能定義在ListNode類里面
ListNode listNode = new ListNode(2);//節(jié)點(diǎn)實(shí)例化,val域賦值為2
}
窮舉法創(chuàng)建鏈表
/MyLinkedList 代表這是一個(gè)鏈表
public class MyLinkedList {
public ListNode head;//鏈表的頭引用,所以定義在鏈表里
public void createList(){
ListNode listNode0 = new ListNode(11);
ListNode listNode1 = new ListNode(26);
ListNode listNode2 = new ListNode(23);
ListNode listNode3 = new ListNode(45);
ListNode listNode4 = new ListNode(56);
listNode0.next = listNode1;
listNode1.next = listNode2;
listNode2.next = listNode3;
listNode3.next = listNode4;
this.head = listNode0;
}
打印鏈表
//打印鏈表
public void display(){
ListNode cur = this.head;
while (cur != null){
System.out.print(cur.val+" ");
cur = cur.next;
}
System.out.println();
}
打印結(jié)果:

查找是否包含關(guān)鍵字key是否在單鏈表當(dāng)中?
//查找是否包含關(guān)鍵字key是否在單鏈表當(dāng)中
public boolean contains(int key) {
ListNode cur = this.head;
while (cur != null) {
if (cur.val == key) {
return true;
}
cur = cur.next;
}
return false;
}
打印結(jié)果:

得到單鏈表的長(zhǎng)度:
//得到單鏈表的長(zhǎng)度
public int size(){
ListNode cur = this.head;
int count = 0;
while(cur != null){
count++;
cur = cur.next;
}
return count;
}
?打印結(jié)果:

頭插法
//頭插法
public void addFirst(int data) {
ListNode node = new ListNode(data);
if (this.head == null) {
this.head = node;
} else {
node.next = this.head;
head = node;
}
}
打印結(jié)果:

尾插法
//尾插法
public void addLast(int data){
ListNode node = new ListNode(data);
ListNode cur = this.head;
if(this.head == null){
this.head = node;
}else {
while(cur.next != null){
cur = cur.next;
}
cur.next = node;
}
}
打印結(jié)果:

任意位置插入,第一個(gè)數(shù)據(jù)節(jié)點(diǎn)為0號(hào)下標(biāo)
public ListNode findIndex(int index){
ListNode cur = this.head;
while(index -1 != 0){
cur = cur.next;
index--;
}
return cur;
}
//任意位置插入,第一個(gè)數(shù)據(jù)節(jié)點(diǎn)為0號(hào)下標(biāo)
public void addIndex(int index,int data){
if(index < 0 || index > size()){
System.out.println("位置不合法");
return;
}
if(index == 0){
addFirst(data);
return;
}
if(index == size()){
addLast(data);
return;
}
ListNode cur = findIndex(index);
ListNode node = new ListNode(data);
node.next = cur.next;
cur.next = node;
}
打印結(jié)果:

刪除第一次出現(xiàn)關(guān)鍵字為key的節(jié)點(diǎn)
//刪除第一次出現(xiàn)關(guān)鍵字為key的節(jié)點(diǎn)
public void remove(int key){
if(this.head == null){
System.out.println("沒有你要?jiǎng)h除的節(jié)");
return;
}
if (this.head.val == key){
this.head = this.head.next;
return;
}
ListNode cur = this.head;
while (cur.next != null){
if(cur.next.val == key){
cur.next = cur.next.next;
return;
}
cur = cur.next;
}
if(cur.next == null){
System.out.println("沒有該節(jié)點(diǎn)");
return;
}
}
打印結(jié)果:

刪除所有值為key的節(jié)點(diǎn)
//刪除所有值為key的節(jié)點(diǎn)
public ListNode removeAllKey(int key){
if(this.head == null) return null;
ListNode prev = this.head;
ListNode cur = this.head;
while (cur != null){
if(cur.val == key){
prev.next = cur.next;
cur = cur.next;
}else{
prev = cur;
cur = cur.next;
}
}
if(this.head.val == key){
this.head = this.head.next;
}
return this.head;
}
打印結(jié)果:

總結(jié):
本文簡(jiǎn)單介紹了數(shù)據(jù)結(jié)構(gòu)的鏈表,如何創(chuàng)建鏈表,鏈表上如何操作數(shù)據(jù)。通過簡(jiǎn)單例題的方式加深對(duì)順序表的理解。上述就是今天的內(nèi)容,有任何疑問的話可以隨時(shí)私信我,文章哪里出現(xiàn)了問題我都會(huì)積極改正,也希望大家能更快的掌握自己想要的知識(shí),讓我們一起加油!?。。?!
到此這篇關(guān)于Java?精煉解讀數(shù)據(jù)結(jié)構(gòu)的鏈表的概念與實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Java 數(shù)據(jù)結(jié)構(gòu)的鏈表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- java數(shù)據(jù)結(jié)構(gòu)基礎(chǔ):單鏈表與雙向鏈表
- Java數(shù)據(jù)結(jié)構(gòu)之順序表和鏈表精解
- Java 數(shù)據(jù)結(jié)構(gòu)之刪除鏈表中重復(fù)的結(jié)點(diǎn)
- Java實(shí)現(xiàn)鏈表數(shù)據(jù)結(jié)構(gòu)的方法
- 帶你了解Java數(shù)據(jù)結(jié)構(gòu)和算法之鏈表
- Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之環(huán)形鏈表
- Java?數(shù)據(jù)結(jié)構(gòu)與算法系列精講之單向鏈表
- Java數(shù)據(jù)結(jié)構(gòu)之雙向鏈表圖解
- Java鏈表數(shù)據(jù)結(jié)構(gòu)及其簡(jiǎn)單使用方法解析
相關(guān)文章
Java+OpenCV實(shí)現(xiàn)人臉檢測(cè)并自動(dòng)拍照
這篇文章主要為大家詳細(xì)介紹了Java+OpenCV實(shí)現(xiàn)人臉檢測(cè),并調(diào)用筆記本攝像頭實(shí)時(shí)抓拍,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07
springboot集成opencv實(shí)現(xiàn)人臉識(shí)別功能的詳細(xì)步驟
大家都知道OpenCV是一個(gè)基于BSD許可(開源)發(fā)行的跨平臺(tái)計(jì)算機(jī)視覺和機(jī)器學(xué)習(xí)軟件庫,可以運(yùn)行在Linux、Windows、Android和Mac OS操作系統(tǒng)上今天通過本文給大家分享springboot集成opencv實(shí)現(xiàn)人臉識(shí)別,感興趣的朋友一起看看吧2021-06-06
spring boot與ktor整合的實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于spring boot與ktor整合的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
單元測(cè)試 @mock與@SpringBootTest的使用
這篇文章主要介紹了單元測(cè)試 @mock與@SpringBootTest的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
Java爬蟲Jsoup+httpclient獲取動(dòng)態(tài)生成的數(shù)據(jù)
這篇文章主要介紹了Java爬蟲Jsoup+httpclient獲取動(dòng)態(tài)生成的數(shù)據(jù)的相關(guān)資料,需要的朋友可以參考下2017-05-05
SchedulingConfigurer實(shí)現(xiàn)動(dòng)態(tài)定時(shí),導(dǎo)致ApplicationRunner無效解決
這篇文章主要介紹了SchedulingConfigurer實(shí)現(xiàn)動(dòng)態(tài)定時(shí),導(dǎo)致ApplicationRunner無效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05

