六種基本排序算法思想及C代碼

描述:給定關鍵字k[0],k[1],key[2],...,key[n-1],對其進行排序(從小到大)

1、  直接插入排序(Straight Insert Sort)

思想:把關鍵字k[i]與有序區的關鍵字進行比較,找到應該插入的位置,然後將其插入。給定待排序列k[0]~k[n-1],則初始有序區爲k[0],直接插入排序可從k=1開始。

代碼:

// 1. StraightInsertion Sort,2014/7/3
void StraightInsertionSort(int key[N])
{
  inti,j ;
  for(i = 1;i <N; i++ )
  {
      inttemp =key[i] ;// it would beoverlaid.
      if(key[i] <key[i-1])
      {
          j= i -1 ;
          while(temp <key[j])
          {
              key[j+1] =key[j] ;
              j -- ;
          }
          key[j+1] =temp ;
      }
  }
}

2、  希爾排序(Shell’s Sort)

思想:又稱“縮小增量排序”,是一種改進的插入排序算法。其需要設置m個增量且有(d[0] > d[1] > …> d[m])。增量的設置準則爲d[0] < N, d[m] = 1,增量需要保證除了1之外沒有公因子;具體有不同的設置方法,且不同的增量會導致算法的效率不同。對於第k趟排序,所有相隔d[k-1]的序列排列爲有序,e.g. 排序之前key[0],key[d[k-1]],key[2*d[k-1]]…,這些爲無序的,經過第k趟排序,這些序列變成有序的。其本質是:直接進行多次(m次)直接插入排序。

代碼:

// 2. ShellSort,2014/7/3
void ShellSort(int key[N],int *d,int m) //m is the length of d
{
  inti,j,k ;
  for(k = 0;k <m;k++)
  {
      for(i =d[k];i < N;i++)
      {
          inttemp =key[i] ;
          if(temp <key[i-d[k]])
          {
              j = i - d[k] ;
             
              while (temp <key[j])
              {
                  key[j+d[k]] =key[j] ;
                  j -= d[k] ;
                  if (j < 0)
                  {
                      break;
                  }
              }
              key[j+d[k]] =temp ;
          }
      }
  }
}

3、  冒泡排序(BubbleSort)

思想:冒泡排序是每次從底部(尾部)開始向上掃描,一趟掃描將最小的上浮至有序區,則第k次掃描的上界爲i-1,下界爲N-1。可以設置一個標誌位(swap= 0,表示有交換),當無交換時將swap設爲1,break,表示排序完成。該方法有種改進方法,雙向冒泡等

代碼:

// 3. Bubble Sort,2014/7/3
int BubbleSort(intkey[N])//return the run ofsort
{
  inti,j ;
  inttemp ;
  intrun = 0 ;
  intswap ;
  for(i = 0;i <N;i ++)
  {
      swap= 0 ;
          for (j =N-1;j >i; j --)
      {
          if (key[j] <key[j-1])
          {
              temp = key[j] ;
              key[j] =key[j-1] ;
              key[j-1] =temp ;
              swap = 1 ;
          }
      }
      if(0 == swap)
      {
          break;
      }
      run++ ;
  }
  return run ;
}

4、  快速排序(QuickSort)

思想:該算法是對冒泡排序的改進,其基本思想是:通過一趟排序,將key[N]分成兩個子序列,然後子序列通過遞歸執行相同操作,直到完成。

實現:分割——通過設置一個low和一個high指針,以及一個pivot基準值,通過左右交替移動,將基準值放到其最終所處位置,而其左邊全小於等於基準值,右邊全大於等於基準值。

         快速排序—對上述的分割進行遞歸調用。

代碼:

int Partition(intkey[],int low, int high)//返回值爲low == high
{
  intpivot =key[low] ;
  while(low <high)
  {
      while(low <high&&key[high]>=pivot)
      {
          high-- ;
      }
      if(low <high)
      {
          key[low] =key[high] ;
          low++ ;
      }
      while(low <high&&key[low]<=pivot)
      {
          low++ ;
      }
      if(low <high)
      {
          key[high] =key[low] ;
          high-- ;
      }
  }
  key[low] =pivot ;
  returnlow ;
}
void QuickSort(int key[N],intlow,inthigh)
{
  inti ;
  if(low <high)
  {
      i= Partition(key,low,high) ;//分割
      QuickSort(key,low,i-1) ;//左邊
      QuickSort(key,i+1,high) ;//右邊
  }
}

5、  直接選擇排序(Select Sort)

思想:每一次從待排序的序列中選出一個最小的放到有序區的末尾,初始有序區爲key[0]

代碼:

// 6. Select Sort,2014/7/3
void SelectSort(int key[N])
{
  inti,j;
  inttemp ;
  for(i = 0;i <N; i ++)
  {
      intk =i ;
      for(j =i+1;j<N;j++)
      {
          if(key[j] <key[k])
          {
              k = j ;
          }
      }
      if(k !=i)
      {
          temp= key[k] ;
          key[k] =key[i] ;
          key[i] =temp ;
      }
  }
}

6、  歸併排序(MergeSort)

思想:將兩個或者兩個以上的有序表合併成一個新的有序表。其基本思路是:

假設初始表含有n個值,則可以看成n個有序的子表,每個有序的子表的長度爲1,然後兩兩歸併,得到Ceil(n/2)個長度爲2或者1(最後一個)個有序表,再兩兩歸併,如此重複,直至得到一個長度爲n的有序表。

代碼:

// 7. Merge Sort,2014/7/3
void Merge(int key[],intlow,intmid,int high)
{
  //mergekey[low]-key[mid] and key[mid+1]-key[high] into one key1[low]- key1[high]
  inti,j,k ;
  i =low ;
  j =mid + 1;
  k =0 ;
  int*key1 ;
  key1= (int *)malloc((high -low + 1)*sizeof(int)) ;
  if(!key1)
  {
      puts("Malloc Error !\n") ;
      exit(0);
  }
 
  while(i <=mid&&j <= high)
  {
      if(key[i] <=key[j])
      {
          key1[k] =key[i] ;
          k++ ;
          i++ ;
      }
      else
      {
          key1[k] =key[j] ;
          k++ ;
          j++ ;
      }
  }
  while( i <= mid)
  {
      key1[k] =key[i] ;
      k++ ;
      i++ ;
  }
  while(j <=high)
  {
      key1[k] =key[j] ;
      k++ ;
      j++ ;
  }
 
  for(k = 0,i =low; i <= high; k++,i++)
  {
      key[i] =key1[k] ;
  }
}
 
void MergePass(int key[],intlength,intn)
{
  inti = 0 ;
  //int j ;
 
  while(i +length*2 - 1 <n)
  {
      Merge(key,i,i+length-1,i+2*length-1) ;
      i+= 2*length ;
  }
  if(i +length - 1<n)
  {
      Merge(key,i,i+length-1,n-1) ;
  }
}
 
void MergeSort(int key[N])
{
  intlength ;
  for(length = 1;length<N; length*= 2)
  {
      MergePass(key,length,N) ;
  }
}


參考文獻:

[1] 軟件技術基礎,西電出版社

[2] C與指針


以上所有程序在VS2010上親測可以運行,歡迎大家來探討。可以直接去如下地址下載,內容相同。

http://download.csdn.net/detail/ai552368625/7646395


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