1. 程式人生 > >氣泡排序在單鏈表中的使用詳解

氣泡排序在單鏈表中的使用詳解

氣泡排序是一種基礎而又簡單的排序方法,它能夠很好地鍛鍊新手思維能力,同樣地,在連結串列的氣泡排序中,它能夠鍛鍊我們連結串列的熟悉使用和對連結串列資料的處理方法。

在對單鏈表進行氣泡排序之前,我們得先掌握三個基礎知識。

氣泡排序

氣泡排序的基本方法是通過兩兩比較,每一趟比較中都會把一個較大的數往後移。

例如:一組數:5,4,3,2,1 從小到大排序

    第一趟比較中:先對第一個數5和4對比,然後5>4,那麼資料交換,然後對第二個數5對第三個數3進行對比,5>3,資料交換,一直這樣對比下去,直到這組資料中

    5移到了最後一位,即這組數變為:4,3,2,1,5;

    然後我們在重複第一趟的步驟,依次比較,然後就把4移到了5的前面;變成3,2,1,4,5;

    依次重複(5-1)次

    ....................

    最後變為了:1,2,3,4,5;

    迴圈分析:對於i個數,我們要進行(i-1)趟比較,然後每一趟迴圈中,我們實際只需要進行(j-i-1)次比較,因為我們第一趟把5移到最後,我們知道了5是這組資料中的

    最大值,然後第二趟迴圈中我們就不用和5進行比較,依次類推下去。

具體的程式碼不是本文的重點,網上有很多相關的案例,可以去搜搜。

連結串列節點的交換

氣泡排序的過程,實際上也是交換的過程,只不過在連結串列中我們交換的不是資料而是節點,雖然同樣可以通過交換資料的方式達到冒泡的結果,但如果節點中的資料非

常多時,效率就會變得非常低,況且這種實現方式並不能帶給我們知識上的幫助。所以我們來看看連結串列節點的交換。

NODE* swap(NODE* head){
	NODE *p,*q;
	int data;
	scanf("%d",&data);
	p=q=head;
	while(p->next!=NULL){
		if(p->data==data){
			if(p==head)head=p->next; //頭指標變為下一個節點 
			else q->next=p->next; //(1)
			q=q->next;//(2)
			p->next=q->next;//(3)
			q->next=p;
			break;
		}
		q=p;	//q指標在p指標前面 
		p=p->next; //p指標後移 
	}
	return head;
} 
具體的連結串列交換圖如下:


當然,這個函式並沒有包含輸入尾節點時的交換,因為我們每一次比較的時候都是和下一個數進行對比,當我們輸入倒數第二個數的時候就已經和最後一個數進行對

比交換了。如果連結串列不熟悉的話,建議大家畫圖分析。

●氣泡排序在連結串列中的實現

其實如果懂得上面兩種知識之後,就可以很容易實現了,我們只需要獲取了資料的總數量之後,然後在迴圈中進行節點的資料的判斷並進行交換即可,實現方法如下:

NODE* maopao(NODE* head){
	NODE *p,*q;
	int num=0,j=0;
	q=head;
	//獲取連結串列的長度 
	while(q!=NULL){
		q=q->next;
		num++;
	}
	//氣泡排序的基本思路 
	for(int i=0;i<num-1;i++)
		{
			p=q=head; 
			j=num-i-1; //減少每一趟迴圈中兩兩比較的次數 
			while(p->next!=NULL&&j!=0){
				j--;
				if(p->data>p->next->data){
					//節點的交換 
					if(p==head) head=p->next;
					else q->next=p->next;
					q->next=p->next;
					q=q->next;
					p->next=q->next;
					q->next=p;
					//執行完上面的過程後,為了能夠讓p順利地執行移動到交換後的下一位 . 
					p=q; 
				}
				q=p; //為了能讓q保持在p的前面 
				p=p->next; //p指標後移,即p變成了在q的前面 
			}
		}
	return head;
} 

如果有疑問或者意見歡迎大家留言提出,表訴可能不太好,望諒解。