1. 程式人生 > >單鏈表的快速排序演算法及其實現

單鏈表的快速排序演算法及其實現

今天聽同學面友錄說道單鏈表是否可以用快速排序演算法,想起自己面百度一面的時候面試官也面到這個問題,由於本人是個小菜鳥,所以花了一個下午的時間整理了一下。

演算法思想對於一個連結串列,以head節點的值作為key,然後遍歷之後的節點,可以得到一個小於key的連結串列和大於等於key的連結串列;由此遞迴可以對兩個連結串列分別進行快速。這裡用到了快速排序的思想即經過一趟排序能夠將小於key的元素放在一邊,將大於等於key的元素放在另一邊;

面試回答:如果面試官問快速排序是否適合單鏈表,答案當然是不適合;但是如果問單鏈表可不可以用快速排序,答案當然是肯定的;下面貼出一段拙劣的程式碼,希望大家修正!

code:

struct LinkNode{
	int value;
	LinkNode* next;
	LinkNode(): value(0), next(NULL) {};
};


void Quicksort(LinkNode* &head, LinkNode* &end){
	LinkNode *head1, *head2, *end1, *end2;	/*	記錄每次分割後前後兩個連結串列的頭尾節點*/
	head1 =  head2 = end1 = end2  = NULL;	
	
	if( head == NULL ) return;	//如果遍歷的當前節點為空,返回

	LinkNode *p, *pre1, *pre2;	/*用於遍歷連結串列將連結串列中的元素分成大於key和小於key兩個部分*/
	p = pre1 = pre2 = NULL;
	
	int key = head->value;
	p = head->next; head->next = NULL;	//將head的值孤立出來
	while( p != NULL ) {
		//小於key的連結串列
		if ( p->value < key ){
			if( !head1 ) { head1 = p; pre1 = p; }
			else{ pre1->next = p; pre1 = p; }
			p = p->next;
			pre1->next = NULL;
		}
		//大於等於key的連結串列
		else{
			if( !head2 ) { head2 = p; pre2 = p; }
			else { pre2->next = p; pre2 = p; }
			p = p->next;
			pre2->next = NULL;
		}
	}

	end1 = pre1; end2 = pre2;	/*產生新連結串列的首尾節點*/

	//對左右兩個連結串列進行遞迴快排
	Quicksort(head1, end1);
	Quicksort(head2, end2);

	//從遞迴棧返回的時候,將key節點和左右兩個連結串列連起來
	//左右連結串列都存在
	if( end1 && head2){
		end1->next = head;	head->next = head2;
		head = head1;	end = end2;}

	//只有左連結串列
	else if(end1) { 
		end1->next = head; 
		end = head;	head = head1; } 

	//只有右連結串列
	else if(head2){ 
		head->next = head2;	end = end2;} 
}