單向鍊錶的反序圖示:
---->[1]---->[2]---->[3]...---->[n]---->[null](原鍊錶)
1->next 2->next 3->next n->next head
head 1->next 2->next 3->next n->next
[null]<----[1]<----[2]<----[3]<----...[n]<----(反序後的鍊錶)
反序也就是頭指標指向最後乙個結點,然後最後乙個結點指向倒數第二個結點,以此類推,直到第乙個結點指向空指標
實現方法:
(1)首先考慮如何能實現整個反序過程,很容易想到必須有乙個指標p1進行讀取每個結點,將每個結點的指向改變,還要有乙個指標p2來儲存每次要更改的那個指向,然後還要有乙個臨時指標p用來儲存需要更改的指標的下乙個指標。
(2)先將各個功能指標初始化,p1指向頭指標,p2指向空指標;
(3)先用p把下乙個要擷取的結點儲存起來,然後開始改變當前結點的指向
(4)改變要指向的結點p2,p1移動到下乙個結點,迴圈遍歷
struct
num *reverse(
struct
*phead)
phead=p1;
//頭指標指向最後,改變順序呢
return
phead;
}
(1)基本思想:
對單鏈表進行選擇排序的基本思想和陣列基本一樣,選擇乙個結點或者元素和其他進行比較,每次找出剩下成員中最小的那個,因為單鏈表和陣列有差異,因此在一些操作上有差別,對於鍊錶,則是選出乙個結點進行比較,然後將最小的結點放入另乙個空煉表中,依次類推,直到將原鍊錶排成有序鍊錶。
(2)單向鍊錶的選擇排序圖示:
---->[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
(3)實現方法:
1.從第乙個結點開始,找到最小的,放進另乙個空煉表中
2.空煉表中放入第乙個結點,形成乙個有序鍊錶,並將找到的結點從原煉表中分離出來,不在讓其參與下一次尋找
3.繼續在原煉表中找最小的,將其放入 有序鍊錶的尾指標的next,然後將其標記為尾指標
4.需注意:
①所找到最小的結點是否是頭結點,需要分情況討論
②所放入的結點是否是第乙個放入的結點,也需要分情況討論
struct num *selectsort(struct num *phead)
} if(first==
null
)
//如果有序鍊錶還是乙個空鍊錶
else
if(min==phead)
//如果找到最小的結點是頭結點
phead=phead
->next
;
//將頭結點指向第二個結點
else
p_min
->next
=min
->next
;
//否則就是去除的結點前驅指向其後繼結點 }
if(first!=
null
)
tail
->next
=null
;
//單鏈表最後乙個結點指向空指標
phead=first;
return
phead;
}
(1)基本思想:
依然和陣列類似,顯示取出第乙個結點作為有序陣列,然後依次將後面的結點插入到相應位置
(2)單向鍊錶的直接插入排序圖示:
---->[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
struct num *insertsort(struct num *phead)
else
t->next
=q;
//完成插入操作
}
return
phead;
}
(1)基本思想:
對鍊錶的氣泡排序和對陣列氣泡排序的基本思想是一樣的,每次比較相鄰兩個數的大小,進行交換。
(2)單鏈表氣泡排序示意圖
單向鍊錶的氣泡排序圖示:
---->[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
有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
[ ]---->[q]---------->[p]---->[ ](排序後)
(3)實現方法:
(1)基本實現思路是,相鄰兩個結點,比較得出較小的結點,將其從原來鍊錶中分離,然後插入到較大結點之前,要注意鍊錶的連續和完整性
(2)設定乙個標記可以將每趟排完序的最後位置記錄下來,下一趟可以到那個位置停止,那個位置以後的結點都已經有序。
struct num *bubblesort(struct num *phead)
} }p1=phead;
//把p1原來儲存的資訊去掉
phead=phead
->next
;
//將頭指標指向原來的頭結點
free(p1);
//釋放p1
p1=null
;
//p1置為空,保證不產生「野指標」,即位址不確定的指標
return
phead;
}
有序鍊錶插入節點示意圖:
---->[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
struct num *sortinsert (struct num *phead, struct num *node)
p=phead; //當有序鍊錶不為空
while(p->num num&&p!=null) //p指向的節點的學號比插入節點的學號小,並且它不等於null
if (p==phead) //剛好插入第乙個節點之前
else
//插入其它節點之後
n+= 1; //插入完畢,節點總數加
return phead;
}
鍊錶的基本操作(插入,刪除,排序 逆置等)
鍊錶是資料結構中最基本的,也是非常經典的,在面試筆試中也是經常出現的題,但是萬變不離其宗,只要掌握了基本的操作,一起盡在掌控。特別要注意的一點是處理時千萬要把是否為頭進行判斷,做為乙個特例,或者建立鍊錶就先固定建立乙個表頭,這樣 就沒這麼多判斷了。includeusing namespace std...
鍊錶的建立 插入 刪除 排序和逆置
鍊錶的結構定義 typedef struct linkedlist node 鍊錶的建立 node create const char ch phead next null return head node create int len else phead next null return hea...
Java 鍊錶的插入和逆置
1 鍊錶的插入操作 頭插 鍊錶的頭插即將cur.next head.next 先將head後的值記錄在插入節點的next裡 然後head.next cur 要注意的是,使用頭插方法操作出來的陣列,如果你依次插入1 2 3 4 5的話,出來就會是5 4 3 2 1 的逆序。實現 private ent...