數據結構複習小結4(排序)

插入排序

基本思想:每次將一個待排序的記錄,按其關鍵字大小插入到前面已經排好序的子序列中,直到插入完成。

----直接插入排序

在有序子列裏找到第i個的位置k,將L[k.....i-1]中元素向後移動一個位置

void InsertSort(ElemType A[],int n){

     int i,j;
     for(i=2;i<=n;i++){

        if(A[i].key<A[i-1].key){
            A[0]=A[i];
            for(j=i-1;A[0].key<A[j].key;--j){
                A[j+1]=A[j];
            }
            A[j+1]=A[0];
        }
     }

}

空間複雜度O(1);時間複雜度O(n^2);適合於順序存儲和鏈式存儲的線性表。

------折半插入排序

   先折半查找出元素的待插入位置,再統一移動插入

順序存儲的線性表的有序子表可以用折半查找來實現;比較次數與元素個數有關,時間複雜度O(n^2)

------希爾排序

 將待排序表分成若干個子表,分別進行直接插入排序,再對全表進行一次直接插入排序。

void ShellSort(ElemType A[],int n){
    for(dk=n/2;dk>=1;dk=dk/2)
        for(i=dk+1;i<=n;++i){

            if(A[i].key<A[i-dk].key){
                A[0]=A[i];
                for(j=i-dk;j>0&&A[0]<A[j];k-=dk){
                    A[j+dk]=A[j];
                }
                A[j+dk]=A[0];
            }
        }
}

時間複雜度O(n^2),不穩定;適用於順序存儲

交換排序

-----冒泡排序

基本思想:待排序表長n,從後往前兩兩比較相鄰元素的值,若爲逆序,交換。

void BubbleSort(ElemType A[],int n){
    for(i=0;i<n-1;i++){
        flag=false;
        for(j=n-1;j>i;j--){
            if(A[j-1].A[j]){
                swap(A[j-1],A[j]);
                flag=true;
            }
        }
        if(flag==false)
            return;
    }    
}

時間複雜:最好O(n),最壞O(n^2)

------快速排序

 基本思想:基於分治法,任取一個元素作爲基準pivot,通過一趟排序劃分兩邊部分,一邊小於pivot,一遍大於等於pivot。pivot放在最終位置,然後分別遞歸的對倆子表重複上述排序。

int partion(int data[],int low,int high)
{  
   int t=data[low];
   while(low<high)
   {
    while(low<high&&data[high]>=t)
    {
      high--;
    }
    data[low]=data[high];
    while(low<high&&data[low]<=t)
    {
      low++;
    }
    data[high]=data[low];
   }
   data[low]=t;
   return low;
}
 
 
void quicksort(int data[],int low,int high)
{
   int part;
  if(low<high)
  {
	 
	  part=partion(data,low,high);
	 // printf("%d\n",part);
	  quicksort(data,low,part-1);
	  quicksort(data,part+1,high);
  }
}

--------------------- 
作者:xulu_258 
來源:CSDN 
原文:https://blog.csdn.net/xulu_258/article/details/51319047 
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!

空間複雜度:最壞情況O(n^2)

不穩定算法

選擇排序

基本思想:每一趟i在後面n-i+1個待排序元素中選取關鍵字最小的元素,作爲有序子序的第i個元素,直到第n-1趟完成。

------簡單選擇排序

時間效率:n(n-1)/2次,O(n^2);不穩定

比較次數與初始狀態無關

------堆排序

樹形選擇排序,特點:將L[n] 看成是一顆完全二叉樹的順序存儲結構,利用完全二叉樹中雙親結點和孩子結點之間的內在關係,在當前無序區選擇最大(小)關鍵字;

小根堆:L(i)<=L(2i) 且L(i)<=L(2i+1)

大根堆:L(i)>=L(2i+1) (1<=i<=n/2);最大元素存放在根結點中

建堆時間:O(n)   時間複雜度:O(nlog2 n)  不穩定

歸併排序和基數排序

--------歸併排序

基本思想:歸併的含義將兩個或兩個以上的有序表組合成一個新的有序表;調用n/2h次算法 ;整個歸併需進行log2 n趟

空間複雜度:O(n)  時間複雜度O(nlog2 n);穩定排序;排序次數與初始狀態無關

--------基數排序

基本思想:基於關鍵字各位的大小進行排序

性能:空間O(r) r個隊列;  時間O(d(n+r)) 與初始狀態無關;穩定

內部排序算法得比較及應用

------時空複雜度

平均情況下時間複雜度O(n^2):簡單選擇排序,直接插入排序,冒泡排序

空間複雜度:簡單選擇排序,插入排序冒泡排序,希爾排序,堆排序藉助常數個輔助空間

        快速排序使用小的輔助棧O(log2 n);二路歸併O(n)

穩定:插入排序,冒泡排序,歸併排序,基數排序

小結:

  1. 若n較小,可以採用直接插入或簡單選擇排序;直接插入排序的移動操作較多,記錄信息本身量大時,用簡單排序
  2. 若文件的初始狀態已按關鍵字基本有序,選擇直接插入或冒泡排序
  3. 若n較大,採用時間複雜度O(nlog2 n)快速排序,堆排序,遞歸排序;快速排序被認爲目前內部排序中最好的方法;堆排序所需的輔助空間少於快速排序,這倆是不穩定排序;
  4. 若n很大,並記錄的關鍵字位數較少且可分解採用基數排序
  5. 記錄本身信息量較大,避免耗費大量時間移動記錄,可用鏈表作爲存儲結構

外部排序

歸併排序

歸併趟數S=logm r(向上取整) 

歸併路數m個元素中關鍵字最小比較m-1次,每趟歸併n個元素需要(n-1)*(m-1)

S趟歸併比較總數:S(n-1)*(m-1)

----置換-選擇算法

初始待排文件F1,初始歸併段文件FO,內存工作區爲WA,內存工作區可容納W個記錄;

步驟:

  1. 從待排文件F1輸入W個記錄到工作區WA
  2. 從內存工作區WA中選出關鍵字最小的記錄MIN
  3. 將MIN記錄輸出到FO中
  4. 若F1未讀完,則從F1輸入下一個記錄到WA
  5. 從WA中所有關鍵字比MIN大的記錄中選出最小的,作爲新的MIN
  6. 重複3-5

 

 

 

 

 

 

 

 

 

 

 

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