快速排序的單鏈表實現


在算法思想上,對於單鏈表的快速排序和對於數組的快速排序基本一致,但是同時也存在很大的區別,導致的原因我們也很容易明白,那就是單鏈表不支持像數組那樣的方便的訪問下標,也就是說我們無法對其進行從末尾向前遍歷。所以我們將第一個鏈表第一個結點的值作為左軸,然后向右進行遍歷,設置一個small指針指向左軸的下一個元素,然后比較如果比左軸小的話,使small指針指向的數據與遍歷到的數據進行交換。最后將左軸元素與small指針指向的元素交換即可。之后就是遞歸。具體圖解如下:

下面附上代碼:

void quicksort(Linklist head, Linklist end){
	if(head == NULL || head == end)             //如果頭指針為空或者鏈表為空,直接返回
		return ;
	int t;
	Linklist p = head -> next;                  //用來遍歷的指針
	Linklist small = head;
	while( p != end){
		if( p -> data < head -> data){      //對於小於軸的元素放在左邊
			small = small -> next;
			t = small -> data;
			small -> data = p -> data;
			p -> data = t;
		}
		p = p -> next;
	}
	t = head -> data;                           //遍歷完后,對左軸元素與small指向的元素交換
	head -> data = small -> data;
	small -> data = t;
	quicksort(head, small);                     //對左右進行遞歸
	quicksort(small -> next, end);
}

此外,對於鏈表,快排還有其他的思路。那就是將基准定下來后,遍歷鏈表,選擇比基准小的連成一個新的子表,選擇比基准大的連成一個新的子表,然后將基准插入,進而再對兩個子表進行遞歸快排

void Quicksort(Linklist *head, Linklist end){
	Linklist right;
	Linklist *p1;
	Linklist *p2;
	Linklist flag;
	Linklist old;
	int num, left_num, right_num;
	if(*head == end)
		return ;
	do{
		flag = *head;                                                  //基准元素
		p1 = head;                                                     //比基准元素小的鏈表
		p2 = &right;                                                   //比基准元素大的鏈表
		left_num = right_num = 0;                                      //記錄兩個鏈表長度的大小
		for(old =(*head) -> next; old != end; old = old -> next){      //遍歷當前函數中的鏈表
			if(old -> data < flag -> data){                        //對於小於基准的元素,放在左鏈表中
				left_num ++;
				*p1 = old;
				p1 = &(old -> next);
			}
			else{
				++right_num;                                   //對於大於基准的元素,放在右鏈表中
				*p2 = old;
				p2 = &(old -> next);
			}
		}
		*p2 = end;                                                     //封死右鏈表
		*p1 = flag;                                                    //將基准插入在兩個鏈表之間
		flag -> next = right;
		if(left_num > right_num){                                      //對長度更小的鏈表進行遞歸快排運算
			Quicksort(&(flag -> next), end);
			end = flag;
			num = left_num;
		}
		else{
			Quicksort(head, flag);
			head = &(flag -> next);
			num = right_num;
		}
	}while(num > 1);
}

對於鏈表中的快速排序暫時說這么多,但是實際上快排是不適合單鏈表的,應用歸並排序效率更好



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM