1. 程式人生 > >排序——選擇排序、快速排序

排序——選擇排序、快速排序

關鍵字 justify 位置 type amp 選擇 兩個 center 們的

知識點總結報告

知識點:

選擇排序

(原理)基本思想:第i趟排序開始時,當前有序區和無序區分別為R[0...i-1]和R[i..n-1](0<=i<n-1),該趟排序是從當前無序區中選出關鍵字最小的元素R[k],將它與無序區的第一個元素R[i]交換,使R[0..i]和R[i+1..n-1]分別變為新的有序區和新的無序區。

  因為每趟排序均使有序區中增加了一個元素,且有序區中元素的關鍵字均不大於無序區中元素的關鍵字,即第i趟排序之後R[0..i]的所有關鍵字均小於等於R[i+1..n-1]中的所有關鍵字,所以進行n-1趟排序之後R[0..n-2]的所有關鍵字小於等於R[n-1].key,也就是說,經過n-1趟排序之後整個表R[0..n-1]遞增有序。

簡單選擇排序算法

void SelectSort(RecType R[ ],int n)

{  int i,j,k;

  for(i=0;i<n-1;i++)

  {  k=i;

    for(j=i+1;j<n;j++)

      if(R[j].key<R[k].key)

        k=j;

    if(k!=j)

      swap(R[i],R[k]);

  }

}

快速排序

(原理)快速排序是由冒泡排序改進而得的,它的基本思想是在待排序的n個元素中任取一個元素(通常取第一個元素)作為基準,把該元素放在適當位置後,數據序列被此元素劃分為兩部分。所有關鍵字比該元素關鍵字小的元素放置在前一部分,所有比它大的元素放置在後一部分,並把該元素排在這兩部分的中間(稱為該元素歸位),這個過程稱為一趟快速排序,及即一趟劃分。

  之後對產生的兩個部分分別重復上述過程,直至每部分內只有一個元素或空為止。簡而言之,每趟使表的第一個元素放入適當位置,將表一分為二,對子表按遞歸方式繼續這種劃分,直至劃分的子表的長度為1或0。

  一趟快速排序的劃分過程partition(R,s,t)是采用從兩頭向中間掃描的辦法,同時交換與基準元素逆序的元素。具體方法是設兩個指示器i和j,它們的初值分別為指向無序區中的第一個和最後一個元素。假設無序區中元素為R[s],R[S+1],...R[t],則i的初值為s,j的初值為t,首先將R[s]移至變量tmp中作為基準,令j自位置t起向前掃描直至R[j].key<tmp.key時將R[i]移至

位置i,然後讓i向後掃描直至R[i].key>tmp.key時將R[i]移至位置j,依次重復直至i=j,此時所有R[k](k=s,s+1...,i-1)的關鍵字都小於tmp.key,而所有R[k](k=i+1,i+2,...,t)的關鍵字必大於tmp.key,此時再將tmp中的元素移至位置i,它將無序區中的元素分割成R[s..i-1]和R[i+1..t],以便分別進行排序。

快速排序算法

int partition(RecType R[ ],int s,int t)      //一趟劃分

{  int i=s,j=t;

  RecTyoe tmp=R[i];          //以R[i]為基準

  while(i<j)              //從兩端交替向中間掃描,直至i=j為止

  {  while(j>i&&R[j].key>=tmp.key)

      j--;            //從右向左掃描,找一個小於tmp.key的R[j]

    R[i]=R[j];            //找到這樣的R[j],放入R[i]處

    while(i<j&&R[i].key<=tmp.key)

      i++;            //從左向右掃描,找一個大於tmp.key的R[i]

    R[j]=R[i];            ////找到這樣的R[i],放入R[j]處

   }

   R[i]=tmp;

   return i;

}

void QuickSort(RecType R[ ],int s, int t)      //對R[s..t]的元素進行快速排序

{  int i;

  if(s<t)                   //區間內至少存在兩個元素的情況

  {  i=partition(R,s,t);

    QuickSort(R,s,i-1);            //對左區間遞歸排序

    QuickSort(R,i+1,t);            //對右區間遞歸排序

  }

}

排序——選擇排序、快速排序