Sort List(四種演算法)

2021-06-30 17:01:35 字數 2906 閱讀 2378

sort a linked list in o(

nlog 

n) time using constant space complexity.

演算法一:快速排序。 因為鍊錶是單向,所以有很多細節要注意,比如quick_sort(p,r)排序的區間其實是[p->next,r->next],因為單向鍊錶不能回頭。

/**

* definition for singly-linked list.

* struct listnode

* };

*/class solution

else q = q->next;

}bool flag = (k->next==q || k==q);

swap(k,q);

quick_sort(p,pk);

if(!flag) quick_sort(k->next,q);

}//當交換相鄰的節點時要特別考慮

void swap(listnode *p, listnode *r)

else

}listnode *sortlist(listnode *head)

};

演算法二: 改進版快速排序。  快速排序在資料隨機分布情況下速度較快,但在本題中會超時。檢視超時的test case,發現有大量重複值。於是想到改進的演算法,拋棄傳統的兩段劃分,採用三段劃分。, , . 每次分割後對中間段不再呼叫quick_sort。改進後可以ac

改進後的快排演算法:

/**

* definition for singly-linked list.

* struct listnode

* };

*/class solution ,,

void quick_sort(listnode *p,listnode *r)

else }}

//若在前面同時出現了大於、等於tail->val的兩種節點,則還要再將等於tail->val的節點與大於tail->val的節點交換

else

} else if(q->next->val == tail->val)

else q = q->next;

} bool flag = (k2->next==q || k2==q);

swap(k2,q);

quick_sort(p,pk1);

if(!flag) quick_sort(k2->next,q);

}//當交換相鄰的節點時要特別考慮

void swap(listnode *p, listnode *r)

else

}listnode *sortlist(listnode *head)

};

演算法三:遞迴版歸併排序。 除了快速排序,當然也可以用歸併排序。鍊錶的歸併排序與陣列的歸併排序唯一不同是陣列可以在o(1)時間取到中點,但鍊錶要花費o(n),有人因此就認為歸併排序不適合鍊錶了,其實不然。即使找中點要花費o(n)又怎樣呢?事實是不管是陣列還是鍊錶,都要有個合併過程,而合併的時間複雜度就是o(n),因此取中點的複雜度是o(1)還是o(n)都不會影響到整個排序的時間複雜度,鍊錶和陣列的歸併排序時間複雜度上僅在於係數的差別而已。都是o(n*log n)

/**

* definition for singly-linked list.

* struct listnode

* };

*/class solution

pair_node list1 = merge_sort(first,slow);

pair_node list2 = merge_sort(slow,last);

return merge(list1,list2);

}pair_node merge(pair_node list1,pair_node list2)

else

while(p!=list1.second && q!=list2.second)

else

}if(p!=list1.second)

else cur->next = q;

return make_pair(first,list2.second);

}listnode *sortlist(listnode *head)

};

因為用歸併排序並不像快排在找分割點的過程中需要交換節點,所以在處理上要比快排容易,只需用乙個首節點和尾節點的後繼表示鍊錶就可以了。

演算法四:非遞迴歸併排序。上面的歸併排序是採用傳統的遞迴實現。歸併排序也可以用迭代實現,實質是遞迴的逆向實現。其思路是這樣,假設有n個節點,從第乙個節點1開始,發現此前沒有已經排好的長度為1的鍊錶(即單個節點),到2時發現此前有單節點1,則把(1,2)合併成長度為2的已排序鍊錶,再看此前有沒有長度為2的已排序的子鍊錶,沒有。再取3,發現此前無單節點(1,2已經合併),再取4,發現有單節點3,合併(3,4),合併後長度為2,再查詢此前有沒有長度為2的已排序子鍊錶,剛好有!於是將子鍊錶(1,2)與子鍊錶(3,4)合併,合併後長度為4......

/*** definition for singly-linked list.

* struct listnode

* };

*/class solution

else

while(ival <= q->val)

else

}if(inext = p;

while(++inext;

p->next = q;

}else cur->next = q;

return res;

}listnode *sortlist(listnode *head)

else{

int len = 1<

四種Block Match演算法

塊匹配block match演算法常用於雙目立體匹配和幀間距離匹配上,特點是實現步驟簡單,這裡介紹四種基本的block match演算法 1.sum of absolute differencse sad 公式如下 c 實現 mat funcsadr2l mat leftimage,mat righ...

排序演算法(四種)

氣泡排序是非常容易理解和實現,以從小到大排序舉例 設陣列長度為n。氣泡排序從前往後遍歷和從後往前遍歷一樣的原理。目標陣列 3,5,2,6,4,9,7,12,11 從前往後 第一波 從第乙個數開始,如果第乙個數大於第二個數,就把這兩個數調換位置,否則保留之前的排列,第二次把第二個和第三個數比較,比較方...

四種洗牌演算法

官方點的話如下 fisher yates shuffle 演算法思想就是從原始陣列中隨機抽取乙個新的數字到新陣列中。演算法描述如下 1.從還沒處理的陣列 假如還剩k個 中,隨機產生乙個 0,k 之間的數字p 假設陣列從0開 始 2.從剩下的k個數中把第p個數取出 3.重複步驟2和3直到數字全部取完 ...