常用排序算法:冒泡、插入、快速、選擇排序

1、冒泡排序:

比較兩個相鄰的元素,將值大的元素交換到右邊

   基本思想:在要排序的一組數中,對當前還未排好序的範圍內的全部數,自上而下對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉較小的往上冒。  即:每當兩相鄰的數比較後發現它們當前排序與排序要求相反時,就將它們互換,即一輪比較後,較大的數被移動到最後面......

   從前往後,依次比較相鄰的兩個數,把較大的數放到後面。一次循環,可以在當前最末尾位置得到一個當前的最大值。

 

  ==》時間複雜度  ==》平方級  

  for(i=0;i<n-1;i++)
    {
        for(j=0;j<n-1-i;j++)
        {
            if(a[j] > a[j+1])
            {
                t = a[j];
                a[j] = a[j+1];
                a[j+1] = t;
            }
        }
    }

 

2、選擇排序:

從數組中找出最小數放在第1個位置,第二個最小數放在第2個位置;

(1)基本思想:在要排序的一組數中,選出最小的一個數與第一個位置的數交換;然後在剩下的數當中再找最小的與第二個位置的數交換,如此循環到倒數第二個數和最後一個數比較爲止。

    2.1小數上浮(先選小數排列,i=0;)

   1)假設數組中的第1個數是最小的數(下標爲min),2)然後依次與剩餘的數進行比較,若還有比第1個數小的數,則該數爲最小的數(該數的下標賦值該min);3)第一輪運行結束後,判斷min的下標是否改變,若改變,則交換數據:最小的數放到前面。

   【設定最小元素爲首元素,則與後續元素比較,刷新最小的元素,最終由小到大排序】

   

    for(i=0;i<n;i++)				//【查找的輪數/次數】
    {
        min = i;
        for(j=i+1;j<n;j++)		//若i後面的元素有比min小的,則上浮
        {
            if(a[min] > a[j])
					min = j;
        }
        if(min != i)				//上浮數據處理
        {
           t = a[i];
           a[i] = a[min];
           a[min] = t;  
        }
    }

 

    2.2 大數下沉(先選大數排列,i=n-1;)

   //【設定最後一個元素爲最大數,之後與其餘元素比較,找到最大數放至最後】

   

for(i=n-1;i>=0;i--)
    {
        max = i;
        for(j=i;j>=0;j--)
        {
            if(a[max] < a[j])
					max = j;
        }
        
	    if(max != i)
        {
            t = a[i];
            a[i] = a[max];
            a[max] = t;
        }
    }

3、插入排序

   基本思想:在要排序的一組數中,假設前面(n-1) [n>=2] 個數已經是排好順序的,現在要把第n個數插到前面的有序數中,使得這n個數也是排好順序的。如此反覆循環,直到全部排好順序。

   插入排序原理:將一組數據分成兩組,分別將其稱爲有序組與待插入組。每次從待插入組中取出一個元素,與有序組的元素進行一一比較(將大數向後移動),並找到合適的位置,將該元素插到有序組當中。

   就這樣,每次插入一個元素,有序組增加,待插入組減少。直到待插入組元素個數爲0。當然,插入過程中涉及到了元素的移動。

4  6  2  5  // 原有數列

4  7  6  2  5  ==》  i=2;  4  6  7  2  5;

4  6  7  2  5  ==》  i=3;4   6  5;   6  7  5

int insert_sort(int a[],int n)
{¯
    int i =0,j=0,t=0;

    for(i=1;i<n;i++)	//i=1;插入時,因假設第a[0]個數據爲有序數列
    {
        t = a[i];		// 先保存待插入的數據,將該數與前面有序隊列的每一個數進行比較,若有序數列比待插入的數大,則有序數列中的數向後移動,直到有序數列中數沒有比待插入的數大的,則插入
        for(j=i; ((j>0) &&(a[j-1] > t));j--)
        {
				// if((a[j-1] > t) 
            	a[j]= a[j-1];	// 與簽名有序數列比較,將大數向後移動
        }
        a[j] = t;	// 有序數列中數沒有比待插入的數大的,則插入
    }
    return 0;
}

insert_sort(a,sizeof(a));

 

4、快速排序

   思路分析:快速排序採用雙向查找的策略,每一趟選擇當前所有子序列中的一個關鍵字作爲樞紐軸(或者基準數據),將子序列中比樞紐軸小的前移,比樞紐軸大的後移,當本趟所有子序列都被樞軸按上述規則劃分完畢後將會得到新的一組更短的子序列,他們將成爲下趟劃分的初始序列集。

   時間複雜度:最好情況(待排序列接近無序)時間複雜度爲O(nlog2n),最壞情況(待排序列接近有序)時間複雜度爲O(n2),平均時間複雜度爲O(nlog2n)。

int  quick_sort(int a[],int head,int tail)
{
    int x = a[head];				// 基準數據備份
    int i = head,j = tail;		// 頭、尾下標標記
    while(i<j)
    {
        while(i<j)
        {
            if(a[j] >= x) j--;	// 從後往前比較
            else
            { a[i] = a[j]; break;}
        }
        while(i<j)
        {
            if(a[i] <= x) i++;	//	從前往後比較
            else{ a[j] = a[i];break;}
        }
    }
    a[i] = x;	// 放入基準數據
    if(head < (i-1)) quick_sort(a,head,i-1);
    if((i+1)< tail)  quick_sort(a,i+1,tail);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章