單鏈表的快速排序和歸併排序

2021-06-25 23:14:12 字數 2764 閱讀 4810

大家可能對一維陣列的快速排序和歸併排序比較熟悉,單鏈表的快速排序和歸併排序本質上與一維陣列相同,但存在細微差別。

先介紹一下單鏈表的快速排序。快速排序的基本函式是partition函式,其功能是以乙個參考節點的內容為參考值,將原陣列的元素進行移位,移位結果

使得參考值節點左側的節點值均小於等於該參考值,參考值節點右側的節點值均大於大於該參考值。很多人比較熟悉的paitition演算法是使用兩個指標分別指向

陣列的頭、尾節點,然後使這兩個節點不斷往中間靠攏的演算法。但是這種演算法對單鏈表並不適用,因為無法通過單鏈表的尾節點直接找到尾節點的前乙個節點。

於是,好多人可能覺得單鏈表無法用快速排序演算法排序。其實不然。還有一種相同複雜度的partition演算法,演算法中參考指標只朝鍊錶的方向移動,使用該partition

演算法即可實現單鏈表的快速排序。

該partition演算法的基本思路為:

1、將鍊錶的第乙個節點的值作為參考值,設定兩個指標p0和p1。p0初始指向鍊錶的第乙個節點,p1初始指向鍊錶的第二個節點。

從鍊錶的首節點到p0節點,這些節點的值都小於等於參考值;p1表示最新遍歷的節點。

2、p1不斷先前推進,每當p1所指節點的值小於參考值,說明新找到乙個值小於參考值的節點,將p0向前推進,然後該節點的值與p0的值交換。從而使得

已經處在正確位置的值小於等於參考值的節點數增加。由於p1每次找到乙個值小於參考值的節點,都會將該節點的值與當前狀態下最前面的乙個值大於參考值

的節點值進行交換。因此,當p1推進到鍊錶的末尾時,就可以保證鍊錶的首節點到p0節點的節點值均小於等於參考值;p0-next到鍊錶末尾的節點值均大於等於

參考值。

3、由於p0的節點值有可能小於參考值。因此,需要將p0的值與鍊錶的首節點的值進行交換。

**如下:

#includeusing namespace std;

struct node

;void qsort(node *head, int n);

int main()

pnode=phead;

node *temp=null;

for(int i=1; i>temp->data;

temp->next=null;

pnode->next=temp;

pnode=temp;

} qsort(phead, n);

pnode=phead;

while(pnode!=null)

coutint ref;

ref=front->data;

int count=1;

int frontnum=0;

while(countdatanext;

++frontnum;

if(front!=rear)

}rear=rear->next;

++count;

} int temp=front->data;

front->data=head->data;

head->data=temp;

qsort(head, frontnum);

qsort(front->next, n-frontnum-1);

}

下面再介紹一下單鏈表的歸併排序方法。

歸併排序的基本思想是分治。將長度為n的陣列等分成前後兩端陣列。先分別對錢後兩端陣列進行歸併排序,然後將前後兩端已經

排好序的子陣列進行合併。 一維陣列可以直接跳過下標以o(1)的複雜度找到前後兩端陣列的分界線,而鍊錶只能通過逐個節點遍歷的方法找到前後

兩端陣列的分界線。想要找到單鏈表的中間節點,可以使用兩個指標。乙個指標p1以2步長向前推進,另乙個指標p0以一步長向前推進。當p1移動到

鍊錶末尾時,p0即鍊錶的中間節點。

實現**如下:

#includeusing namespace std;

struct node

;node* mergesort(node *head, node *rear);

int main()

pnode=phead;

node *temp=null;

for(int i=1; i>temp->data;

temp->next=null;

pnode->next=temp;

pnode=temp;

} phead=mergesort(phead, pnode);

pnode=phead;

while(pnode!=null)

coutif(head==rear)

return head;

node *p0=head, *p1=head;

while(p1->next!=null) }

node *head1=p0->next;

node* pfront=mergesort(head, p0);

node* pbehind=mergesort(head1, rear);

node *reshead=null;

if(pfront->data < pbehind->data)

else

node *ptemp=reshead;

while(pfront!=null && pbehind!=null)

else

}if(pfront!=null)

ptemp->next=pfront;

else

ptemp->next=pbehind;

return reshead;

}

單鏈表歸併排序

1 對於鍊錶來說,由於其元素的訪問只能是順序訪問,而快速排序是改進後的氣泡排序,需要隨機訪問資料,不合適。採用歸併排序方式對鍊錶元素進行訪問 2 需要的步驟 1 分割 將一段鍊錶分成兩部分 2 排序 將兩端已經有序的鍊錶合併 3 分治遞迴 遞迴操作 將鍊錶plist分割,並把分割後的兩段鍊錶第乙個元...

單鏈表的歸併排序

題目 單鏈表的歸併排序 思路 首先找到鍊錶的中間節點,將原始鍊錶一分為二,遞迴進行該操作,直到被劃分的兩個鍊錶包含的節點少於等於1個,即該次劃分後兩個鍊錶已經有序。然後依次合併兩個有序的鍊錶,直到所有劃分都合併完,即排序完畢。主要編寫將兩個有序鍊錶合併為乙個有序鍊錶的函式。includeusing ...

單鏈表的歸併排序

question 148.sort list sort a linked list in o n log n time using constant space complexity.中文 使用恆定的空間複雜度排序乙個鍊錶,要求時間複雜度是o nlogn 我們知道題目的要求是時間複雜度是o nlog...