連結串列操作
連結串列概述
連結串列是一種常見的重要的資料結構。它是動態地進行儲存分配的一種結構。它可以根據需要開闢記憶體單元。連結串列有一個“頭指標”變數,以head表示,它存放一個地址。該地址指向一個元素。連結串列中每一個元素稱為“結點”,每個結點都應包括兩個部分:一為使用者需要用的實際資料,二為下一個結點的地址。因此,head指向第一個元素:第一個元素又指向第二個元素;……,直到最後一個元素,該元素不再指向其它元素,它稱為“表尾”,它的地址部分放一個“NULL”(表示“空地址”),連結串列到此結束。
連結串列的各類操作包括:學習單向連結串列的建立、刪除、 插入(無序、有序)、輸出、 排序(選擇、插入、冒泡)、反序等等。
單向連結串列的圖示:
---->[NULL]
head
圖1:空連結串列
---->[p1]---->[p2]...---->[pn]---->[NULL]
head p1->next p2->next pn->next
圖2:有N個節點的連結串列
建立n個節點的連結串列的函式為:
輸出連結串列中節點的函式為:
單向連結串列的刪除圖示:
---->[NULL]
head
圖3:空連結串列
從圖3可知,空連結串列顯然不能刪除
---->[1]---->[2]...---->[n]---->[NULL](原連結串列)
head 1->next 2->next n->next
---->[2]...---->[n]---->[NULL](刪除後連結串列)
head 2->next n->next
圖4:有N個節點的連結串列,刪除第一個節點
結合原連結串列和刪除後的連結串列,就很容易寫出相應的程式碼。操作方法如下:
1、你要明白head就是第1個節點,head->next就是第2個節點;
2、刪除後head指向第2個節點,就是讓head=head->next,OK這樣就行了。
---->[1]---->[2]---->[3]...---->[n]---->[NULL](原連結串列)
head 1->next 2->next 3->next n->next
---->[1]---->[3]...---->[n]---->[NULL](刪除後連結串列)
head 1->next 3->next n->next
圖5:有N個節點的連結串列,刪除中間一個(這裡圖示刪除第2個)
結合原連結串列和刪除後的連結串列,就很容易寫出相應的程式碼。操作方法如下:
1、你要明白head就是第1個節點,1->next就是第2個節點,2->next就是第3個節點;
2、刪除後2,1指向第3個節點,就是讓1->next=2->next。
刪除指定學號的節點的函式為:
單向連結串列的插入圖示:
---->[NULL](原連結串列)
head
---->[1]---->[NULL](插入後的連結串列)
head 1->next
圖7 空連結串列插入一個節點
結合原連結串列和插入後的連結串列,就很容易寫出相應的程式碼。操作方法如下:
1、你要明白空連結串列head指向NULL就是head=NULL;
2、插入後head指向第1個節點,就是讓head=1,1->next=NULL,OK這樣就行了。
---->[1]---->[2]---->[3]...---->[n]---->[NULL](原連結串列)
head 1->next 2->next 3->next n->next
---->[1]---->[2]---->[x]---->[3]...---->[n]---->[NULL](插入後的連結串列)
head 1->next 2->next x->next 3->next n->next
圖8:有N個節點的連結串列,插入一個節點(這裡圖示插入第2個後面)
結合原連結串列和插入後的連結串列,就很容易寫出相應的程式碼。操作方法如下:
1、你要明白原1->next就是節點2,2->next就是節點3;
2、插入後x指向第3個節點,2指向x,就是讓x->next=2->next,1->next=x。
插入指定節點的後面的函式為:
單向連結串列的反序圖示:
---->[1]---->[2]---->[3]...---->[n]---->[NULL](原連結串列)
head 1->next 2->next 3->next n->next
[NULL]<----[1]<----[2]<----[3]<----...[n]<----(反序後的連結串列)
1->next 2->next 3->next n->next head
圖9:有N個節點的連結串列反序
結合原連結串列和插入後的連結串列,就很容易寫出相應的程式碼。操作方法如下:
1、我們需要一個讀原連結串列的指標p2,存反序連結串列的p1=NULL(剛好最後一個節點的next為NULL),還有一個臨時儲存變數p;
2、p2在原連結串列中讀出一個節點,我們就把它放到p1中,p就是用來處理節點放置順序的問題;
3、比如,現在我們取得一個2,為了我們繼續往下取節點,我們必須儲存它的next值,由原連結串列可知p=2->next;
4、然後由反序後的連結串列可知,反序後2->next要指向1,則2->next=1;
5、好了,現在已經反序一個節點,接著處理下一個節點就需要儲存此時的資訊:
p1變成剛剛加入的2,即p1=2;p2要變成它的下一節點,就是上面我們儲存的p,即p2=p。
反序連結串列的函式為:
對連結串列進行選擇排序的基本思想就是反覆從還未排好序的那些節點中,選出鍵值(就是用它排序的欄位,我們取學號num為鍵值)最小的節點,依次重新組合成一個連結串列。
我認為寫連結串列這類程式,關鍵是理解:head儲存的是第一個節點的地址,head->next儲存的是第二個節點的地址;任意一個節點p的地址,只能通過它前一個節點的next來求得。
單向連結串列的選擇排序圖示:
---->[1]---->[3]---->[2]...---->[n]---->[NULL](原連結串列)
head 1->next 3->next 2->next n->next
---->[NULL](空連結串列)
first
tail
---->[1]---->[2]---->[3]...---->[n]---->[NULL](排序後連結串列)
first 1->next 2->next 3->next tail->next
圖10:有N個節點的連結串列選擇排序
1、先在原連結串列中找最小的,找到一個後就把它放到另一個空的連結串列中;
2、空連結串列中安放第一個進來的節點,產生一個有序連結串列,並且讓它在原連結串列中分離出來(此時要注意原連結串列中出來的是第一個節點還是中間其它節點);
3、繼續在原連結串列中找下一個最小的,找到後把它放入有序連結串列的尾指標的next,然後它變成其尾指標;
對連結串列進行選擇排序的函式為:
對連結串列進行直接插入排序的基本思想就是假設連結串列的前面n-1個節點是已經按鍵值(就是用它排序的欄位,我們取學號num為鍵值)排好序的,對於節點n在這個序列中找插入位置,使得n插入後新序列仍然有序。按照這種思想,依次對連結串列從頭到尾執行一遍,就可以使無序連結串列變為有序連結串列。
單向連結串列的直接插入排序圖示:
---->[1]---->[3]---->[2]...---->[n]---->[NULL](原連結串列)
head 1->next 3->next 2->next n->next
---->[1]---->[NULL](從原連結串列中取第1個節點作為只有一個節點的有序連結串列)
head
圖11
---->[3]---->[2]...---->[n]---->[NULL](原連結串列剩下用於直接插入排序的節點)
first 3->next 2->next n->next
圖12
---->[1]---->[2]---->[3]...---->[n]---->[NULL](排序後連結串列)
head 1->next 2->next 3->next n->next
圖13:有N個節點的連結串列直接插入排序
1、先在原連結串列中以第一個節點為一個有序連結串列,其餘節點為待定節點。
2、從圖12連結串列中取節點,到圖11連結串列中定位插入。
3、上面圖示雖說畫了兩條連結串列,其實只有一條連結串列。在排序中,實質只增加了一個用於指向剩下需要排序節點的頭指標first罷了。
這一點請讀者務必搞清楚,要不然就可能認為它和上面的選擇排序法一樣了。
對連結串列進行直接插入排序的函式為:
對連結串列進行氣泡排序的基本思想就是對當前還未排好序的範圍內的全部節點,自上而下對相鄰的兩個節點依次進行比較和調整,讓鍵值(就是用它排 序的欄位,我們取學號num為鍵值)較大的節點往下沉,鍵值較小的往上冒。即:每當兩相鄰的節點比較後發現它們的排序與排序要求相反時,就將它們互換。
單向連結串列的氣泡排序圖示:
---->[1]---->[3]---->[2]...---->[n]---->[NULL](原連結串列)
head 1->next 3->next 2->next n->next
---->[1]---->[2]---->[3]...---->[n]---->[NULL](排序後連結串列)
head 1->next 2->next 3->next n->next
圖14:有N個節點的連結串列氣泡排序
任意兩個相鄰節點p、q位置互換圖示:
假設p1->next指向p,那麼顯然p1->next->next就指向q,
p1->next->next->next就指向q的後繼節點,我們用p2儲存
p1->next->next指標。即:p2=p1->next->next,則有:
[ ]---->[p]---------->[q]---->[ ](排序前)
p1->next p1->next->next p2->next
圖15
[ ]---->[q]---------->[p]---->[ ](排序後)
圖16
1、排序後q節點指向p節點,在調整指向之前,我們要儲存原p的指向節點地址,即:p2=p1->next->next;
2、順著這一步一步往下推,排序後圖16中p1->next->next要指的是p2->next,所以p1->next->next=p2->next;
3、在圖15中p2->next原是q發出來的指向,排序後圖16中q的指向要變為指向p的,而原來p1->next是指向p的,所以p2->next=p1->next;
4、在圖15中p1->next原是指向p的,排序後圖16中p1->next要指向q,原來p1->next->next(即p2)是指向q的,所以p1->next=p2;
5、至此,我們完成了相鄰兩節點的順序交換。
6、下面的程式描述改進了一點就是記錄了每次最後一次節點下沉的位置,這樣我們不必每次都從頭到尾的掃描,只需要掃描到記錄點為止。 因為後面的都已經是排好序的了。
對連結串列進行氣泡排序的函式為:
有序連結串列插入節點示意圖:
---->[NULL](空有序連結串列)
head
圖18:空有序連結串列(空有序連結串列好解決,直接讓head指向它就是了。)
以下討論不為空的有序連結串列。
---->[1]---->[2]---->[3]...---->[n]---->[NULL](有序連結串列)
head 1->next 2->next 3->next n->next
圖18:有N個節點的有序連結串列
插入node節點的位置有兩種情況:一是第一個節點前,二是其它節點前或後。
---->[node]---->[1]---->[2]---->[3]...---->[n]---->[NULL]
head node->next 1->next 2->next 3->next n->next
圖19:node節點插在第一個節點前
---->[1]---->[2]---->[3]...---->[node]...---->[n]---->[NULL]
head 1->next 2->next 3->next node->next n->next
插入有序連結串列的函式為:
綜上所述,連結串列的各類操作函式的完整程式碼如下:
相關文章
- 資料結構之連結串列篇(單連結串列的常見操作)資料結構
- 資料結構之連結串列操作資料結構
- 4-雙連結串列的操作
- 02-單連結串列的操作
- 連結串列 - 單向連結串列
- 連結串列-迴圈連結串列
- 連結串列-雙向連結串列
- golang二級指標操作連結串列Golang指標
- 演算法 - 連結串列操作思想 && case演算法
- 連結串列4: 迴圈連結串列
- 連結串列-雙向通用連結串列
- 連結串列-單連結串列實現
- C++資料結構連結串列的基本操作C++資料結構
- 連結串列-雙向非通用連結串列
- 【LeetCode】->連結串列->通向連結串列自由之路LeetCode
- 連結串列入門與插入連結串列
- Leetcode_86_分割連結串列_連結串列LeetCode
- 資料結構-單連結串列、雙連結串列資料結構
- 連結串列
- LeetCode-Python-86. 分隔連結串列(連結串列)LeetCodePython
- C++單連結串列遞迴遍歷操作C++遞迴
- 建立連結串列並進行增加、刪減操作
- 單連結串列建立連結串列出現問題
- **203.移除連結串列元素****707.設計連結串列****206.反轉連結串列**
- php連結串列PHP
- 連結串列逆序
- 2、連結串列
- 連結串列(python)Python
- 重排連結串列
- 單連結串列
- 分割連結串列
- (一)連結串列
- 資料結構與演算法——連結串列 Linked List(單連結串列、雙向連結串列、單向環形連結串列-Josephu 問題)資料結構演算法
- 2024.04.19每日收穫之連結串列與邏輯操作
- C語言單向連結串列的增刪操作C語言
- 【LeetCode-連結串列】面試題-反轉連結串列LeetCode面試題
- 資料結構之連結串列:206. 反轉連結串列資料結構
- 反轉連結串列、合併連結串列、樹的子結構
- [連結串列】2.輸入一個連結串列,反轉連結串列後,輸出新連結串列的表頭。[多益,位元組考過]