演算法基礎——1.排序

來源:互聯網
上載者:User

標籤:最佳化   swa   資料結構   希爾排序   最小值   演算法分析   mina   直接   有序   

排序演算法

交換排序類:冒泡排序、快速排序

選擇排序類:簡單選擇排序、堆排序

插入排序類:直接插入排序、希爾排序

冒泡排序

冒泡排序(Bubble Sort),排序的基本思想為兩兩比較小相鄰資料的關鍵字,如果順序為反則進行交換,直到沒有反序的記錄為止。

冒泡排序有多種變化,其三種不同實現的代碼如下:

//OS:Win    | Terminal:Cmder | Editor:Atom | Language:cvoid Swap(int *a , int *b){    int temp = *a;    *a = *b;    *b = temp;}//最容易的排序,從第一個元素開始向後與每一個元素進行比較,交換得到最小的元素,放在第i個位置//這樣排序進行較多次無用的比較,當然,這並不是所謂的冒泡排序void SimpleBubble(int array[] , int length){    for(int i = 0 ; i < length ; i++){        for(int j = i+1 ; j < length ; j++){            if(array[i] > array[j]){                Swap(&array[i],&array[j]);            }        }    }}//從第一個位置開始,由下往上兩兩元素進行比較,判斷並交換得到最小值//這樣排序依次迴圈確定第i個位置的元素void LittleBubble(int array[] ,int length){    for(int i =0 ; i < length ; i++){        for(int j = length -1 ; j > i ;j --){            if(array[j] < array[j-1]){                Swap(&array[j],&array[j-1]);            }        }    }}//增加標誌位isSwap來表示是否存在反序或者是否進行過交換操作//直到序列沒有反序記錄為止void BubbleSort(int array[] , int length){    int isSwap = 1;    for(int i = 0 ; i < length ; i ++){        if(isSwap){            isSwap = 0;            for(int j = length -1 ; j > i ; j --){                if(array[j] < array[j-1]){                    Swap(&array[j],&array[j-1]);                    isSwap = 1;                }            }        }    }}void Print(int array[] , int length){    for (int i = 0 ; i < length ;i++){        printf(" %d",array[i]);    }}int main(){    int array[] = {6,5,3,1,0,2,9,8,4,7};    BubbleSort(array,10);    Print(array,10);    return 0;}
簡單選擇排序

簡單選擇排序(Simple Selection Sort),基本思想是:標記第i個元素為最小值下標min開始向後進行遍曆比較,不斷更新最小值下標min,結束該次迴圈後判斷min是否改變,若改變即交換i位置元素及min位置的最小元素。

void SelectSort(int array[] , int length){  int min;  for(int i = 0 ; i <length ; i++){    min  = i ;  //Notice1:以第一個元素為最小開始向後遍曆比較    for(int j = i+1 ; j < length ; j++){  //Notice2:j從i+1開始向後遍曆      if(array[j] < array[min]){  //Notice3:每次都是array[j]與array[min]進行比較,來確定和更新最小值所在下標        min = j;      }    }    if(min != i){      Swap(&array[i] ,&array[min]);    }  }}
直接插入排序

直接插入排序(Straight Insertion Sort)是最簡單的排序演算法之一,主要思想是保證位置0到第i-1位置上的元素為已排序狀態,即插入排序利用這樣的事實,從i位置迴圈進行排序。

void InsertionSort(int array[] , int length ){  int i,j,temp;  //Notice1:開始以第一個資料為有序序列,從第二個資料開始排序  for(i = 1 ; i <length ; i++){    if(array[i] < array[i-1]){  //Notice2:噹噹前資料大於前一個時,開始向前插入      temp = array[i];  //儲存此時的值,為前方較大元素空出位置      for(j = i -1 ; j>=0 && array[j] > temp ; j--){  //向前迴圈直至下標小於0,或者值比當前值更小        array[j+1] = array[j];  //依次後移      }      array[j+1] = temp;  //此時j位置的元素小於當前值,所以插入其後一位j+1即可    }  }}
希爾排序

希爾排序(Shell Sort)是衝破二次時間屏障的第一批演算法之一。主要思想是:通過比較一定間隔的元素來工作;各趟比較所用的距離(希爾增量)隨著演算法的進行而逐漸減小,直到比較相元素的最後一趟排序為止。因此,希爾排序也稱為縮小增量排序。

void ShellSort(int array[] , int length){    int i,j,temp,gap;    int judgeCount = 0, changeCount = 0;    //Notice1:設定希爾增量序列初始值 gap = length/2 ,一直迴圈值gap=1進行最後一次插入排序    for(gap = length/2 ; gap >0 ; gap /=2){    //Notice2:內層嵌套一個直接插入迴圈        for(i = gap ; i < length ; i++ ){            judgeCount++;            if(array[i] < array[i - gap]){                temp = array[i];                for(j = i - gap ; j >= 0 && array[j] > temp ; j -=gap){                    array[j+gap] = array[j];                    changeCount++;                }                array[j+gap] = temp;            }        }    }    printf("Judge Count : %d ,Change Count : %d .\n", judgeCount,changeCount);}
堆排序

堆排序(Heap Sort)是一個非常穩定的演算法,排序平均使用的比較只比最壞情況界指出的略少。

void AdjustHeap(int array[] , int i , int length){  //Notice2:儲存開始節點的值為temp,減少直接交換的次數  int temp = array[i];  for(int j = i*2 +1 ; j <length ; j = j*2+1){    if(j+1 < length && array[j] < array[j+1])      j++;    if(array[j] < temp )  //Notice3:迴圈對temp中儲存的值進行比較      break;    array[i] = array[j];    i = j;  }  array[i] = temp;  //Notice4:最後在temp合適的位置上進行賦值放置}void HeapSort(int array[] ,int length){  //Notice1:首先從最後一個非頁子節點開始,由右向左、由下至上開始進行最大堆的構造  for(int i = length/2 ; i >= 0 ; i --){    AdjustHeap(array , i ,length);  }  for(int i = length -1 ; i > 0 ; i --){    Swap(&array[0],&array[i]);    AdjustHeap(array, 0, i );  }}
快速排序

快速排序(Quick Sort)是在實踐中最快的已知排序演算法,平均已耗用時間是O(N log N)。快速排序之所以快是因為其精鍊的、高度最佳化的內部迴圈。最壞情況的效能為O(N2),如今高度最佳化後的快速排序簡單易懂並且不難證明。

和歸併排序一樣,快速排序也是一種分治的遞迴演算法。

將數組array進行快速排序QuickSort的基本演算法由以下簡單的四步組成:

  • 1.如果數組長度為0或者1,則直接返回;
  • 2.使用Median3或其他方法擷取樞紐元素pivot;
  • 3.劃分子集;
  • 4.遞迴調用QuickSort
REF

書籍:

資料結構與演算法分析、大話資料結構

演算法基礎——1.排序

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.