10種排序方法

來源:互聯網
上載者:User

一、冒泡(Bubble)排序

void BubbleSortArray(){      for(int i=1;i<n;i++)      {        for(int j=0;i<n-i;j++)         {              if(a[j]>a[j+1])//比較交換相鄰元素               {                   int temp;                   temp=a[j]; a[j]=a[j+1]; a[j+1]=temp;               }         }      }}

二、選擇排序

 

void SelectSortArray(){    int min_index;    for(int i=0;i<n-1;i++)    {         min_index=i;         for(int j=i+1;j<n;j++)//每次掃描選擇最小項            if(arr[j]<arr[min_index])  min_index=j;         if(min_index!=i)//找到最小項交換,即將這一項移到列表中的正確位置         {             int temp;             temp=arr[i]; arr[i]=arr[min_index]; arr[min_index]=temp;}}}

 

三、插入排序

 

void InsertSortArray(){for(int i=1;i<n;i++)//迴圈從第二個數組元素開始,因為arr[0]作為最初已排序部分{    int temp=arr[i];//temp標記為未排序第一個元素    int j=i-1;while (j>=0 && arr[j]>temp)/*將temp與已排序元素從小到大比較,尋找temp應插入的位置*/{    arr[j+1]=arr[j];    j--;}arr[j+1]=temp;}}

四、殼(Shell)排序

 

 

void ShellSortArray(){  for(int incr=3;incr<0;incr--)//增量遞減,以增量3,2,1為例{       for(int L=0;L<(n-1)/incr;L++)//重複分成的每個子列表{   for(int i=L+incr;i<n;i+=incr)//對每個子列表應用插入排序   {      int temp=arr[i];      int j=i-incr;      while(j>=0&&arr[j]>temp)      {          arr[j+incr]=arr[j];          j-=incr;}arr[j+incr]=temp;}}}}

五、歸併排序五、歸併排序

 

void MergeSort(int low,int high){   if(low>=high)   return;//每個子列表中剩下一個元素時停止   else int mid=(low+high)/2;/*將列表劃分成相等的兩個子列表,若有奇數個元素,則在左邊子列表大於右側子列表*/   MergeSort(low,mid);//子列表進一步劃分   MergeSort(mid+1,high);   int [] B=new int [high-low+1];//建立一個數組,用於存放歸併的元素   for(int i=low,j=mid+1,k=low;i<=mid && j<=high;k++)/*兩個子列表進行排序歸併,直到兩個子列表中的一個結束*/   {       if (arr[i]<=arr[j];){    B[k]=arr[i];    I++;}else    { B[k]=arr[j]; j++; }}for(   ;j<=high;j++,k++)//如果第二個子列表中仍然有元素,則追加到新列表      B[k]=arr[j];   for(   ;i<=mid;i++,k++)//如果在第一個子列表中仍然有元素,則追加到新列表中      B[k]=arr[i];   for(int z=0;z<high-low+1;z++)//將排序的數組B的 所有元素複製到原始數組arr中      arr[z]=B[z];}

六、快速排序

 

        int Partition(int [] arr,int low,int high)        {            int pivot=arr[low];//採用子序列的第一個元素作為樞紐元素            while (low < high)            {                //從後往前栽後半部分中尋找第一個小於樞紐元素的元素                while (low < high && arr[high] >= pivot)                {                    --high;                }                //將這個比樞紐元素小的元素交換到前半部分                swap(arr[low], arr[high]);                //從前往後在前半部分中尋找第一個大於樞紐元素的元素                while (low <high &&arr [low ]<=pivot )                {                    ++low ;                }                swap (arr [low ],arr [high ]);//將這個樞紐元素大的元素交換到後半部分            }            return low ;//返回樞紐元素所在的位置        }        void QuickSort(int [] a,int low,int high)        {            if (low <high )            {                int n=Partition (a ,low ,high );                QuickSort (a ,low ,n );                QuickSort (a ,n +1,high );            }        }

 

七、堆排序

 

void HeapSort(SeqIAst R){    //對R[1..n]進行堆排序,不妨用R[0]做暫存單元    int I;    BuildHeap(R); //將R[1-n]建成初始堆    for(i=n;i>1;i--) //對當前無序區R[1..i]進行堆排序,共做n-1趟。    {        R[0]=R[1];        R[1]=R[i];        R[i]=R[0]; //將堆頂和堆中最後一個記錄交換        Heapify(R,1,i-1);  //將R[1..i-1]重新調整為堆,僅有R[1]可能違反堆性質    }}

八、拓撲排序八、拓撲排序

 

void TopologicalSort()/*輸出拓撲排序函數。若G無迴路,則輸出G的頂點的一個拓撲序列並返回OK,否則返回ERROR*/{      int indegree[M];      int i,k,j;      char n;      int count=0;      Stack thestack;      FindInDegree(G,indegree);//對各頂點求入度indegree[0....num]      InitStack(thestack);//初始化棧      for(i=0;i<G.num;i++)          Console.WriteLine("結點"+G.vertices[i].data+"的入度為"+indegree[i]);      for(i=0;i<G.num;i++)      {           if(indegree[i]==0)              Push(thestack.vertices[i]);      }      Console.Write("拓撲排序輸出順序為:");      while(thestack.Peek()!=null)      {               Pop(thestack.Peek());               j=locatevex(G,n);               if (j==-2)                  {                         Console.WriteLine("發生錯誤,程式結束。");                         exit();                  }                Console.Write(G.vertices[j].data);                count++;                for(p=G.vertices[j].firstarc;p!=NULL;p=p.nextarc)                {                     k=p.adjvex;                     if (!(--indegree[k]))                         Push(G.vertices[k]);                }      }      if (count<G.num)          Cosole.WriteLine("該圖有環,出現錯誤,無法排序。");      else          Console.WriteLine("排序成功。");}

 

九、錦標賽排序(轉)

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#define SIZE 100000#define MAX 1000000struct node{ long num;//關鍵字 char str[10]; int lastwin;//最後勝的對手 int killer;//被擊敗的對手 long times;//比賽次數}data[SIZE];long CompareNum=0;long ExchangeNum=0;long Read(char name[])//讀取檔案a.txt中的資料,並存放在數組data[]中;最後返回資料的個數{ FILE *fp; long i=1; fp=fopen(name,"rw"); fscanf(fp,"%d%s",&data[i].num,data[i].str); while(!feof(fp)) {  i++;  fscanf(fp,"%d%s",&data[i].num,data[i].str); } return (i-1);}long Create(long num)//建立勝者樹,返回冠軍(最小數)在數組data[]中的下標{ int i,j1,j2,max,time=1; long min;//記錄當前冠軍的下標 for(i=1;pow(2,i-1)<num;i++)  ; max=pow(2,i-1);//求葉子結點數目 for(i=1;i<=max;i++)//初始化葉子結點 {  data[i].killer=0;  data[i].lastwin=0;  data[i].times=0;  if(i>num)   data[i].num=MAX; } for(i=1;i<=max;i+=2)//第一輪比賽 {  ++CompareNum;  if(data[i].num <= data[i+1].num)  {   data[i].lastwin = i+1;   data[i+1].killer=i;   ++data[i].times;   ++data[i+1].times;   min=i;  }  else  {   data[i+1].lastwin=i;   data[i].killer=i+1;   ++data[i].times;   ++data[i+1].times;   min=i+1;  } } j1=j2=0;//記錄連續的兩個未被淘汰的選手的下標 while(time <= (log(max)/log(2)))//進行淘汰賽 {  for(i=1;i<=max;i++)  {   if(data[i].times==time && data[i].killer==0)//找到一名選手   {    j2=i;//預設其為兩選手中的後來的    if(j1==0)//如果第一位置是空的,則剛來的選手先來的     j1=j2;    else//否則剛來的選手是後來的,那麼選手都已到場比賽開始    {     ++CompareNum;     if(data[j1].num <= data[j2].num)//先來的選手獲勝     {      data[j1].lastwin = j2;//最後贏的是j2      data[j2].killer=j1;//j2是被j1淘汰的      ++data[j1].times;      ++data[j2].times;//兩選手場次均加1      min=j1;//最小數下標為j1      j1=j2=0;//將j1,j2置0     }     else//同理     {      data[j2].lastwin=j1;      data[j1].killer=j2;      ++data[j1].times;      ++data[j2].times;      min=j2;      j1=j2=0;     }    }   }  }  time++;//輪數加1 } return min;//返回冠軍的下標}void TournamentSort(long num)//錦標賽排序{ long tag=Create(num);//返回最小數下標 FILE *fp1; fp1=fopen("sort.txt","w+");//為寫入建立並開啟檔案sort.txt while(data[tag].num != MAX)//當最小值不是無窮大時 {  printf("%d %s\n",data[tag].num,data[tag].str);//輸出資料  fprintf(fp1,"%d %s\n",data[tag].num,data[tag].str);//寫入資料  data[tag].num=MAX;//將當前冠軍用無窮大替換  tag=Create(num);//返回下一個冠軍的下標 }}int main(){ int num; char name[10]; printf("Input name of the file:"); gets(name); num=Read(name);//讀檔案 TournamentSort(num);//錦標賽排序 printf("CompareNum=%d\nExchangeNum=%d\n",CompareNum,ExchangeNum); return 0;}

十、基數排序

十、基數排序(轉 C#)

using System;  using System.Collections.Generic;  using System.Linq;  using System.Text;  namespace LearnSort  {  class Program  {  static void Main(string[] args)  {  int[] arr = CreateRandomArray(10);//產生隨機數組  Print(arr);//輸出數組  RadixSort(ref arr);//排序  Print(arr);//輸出排序後的結果  Console.ReadKey();  }  public static void RadixSort(ref int[] arr)  {  int iMaxLength = GetMaxLength(arr);  RadixSort(ref arr, iMaxLength);  }  private static void RadixSort(ref int[] arr, int iMaxLength)  {  List<int> list = new List<int>();//存放每次排序後的元素  List<int>[] listArr = new List<int>[10];//十個桶  char currnetChar;//存放當前的字元比如說某個元素123 中的2  string currentItem;//存放當前的元素比如說某個元素123  for (int i = 0; i < listArr.Length; i++)//給十個桶分配記憶體初始化。  listArr[i] = new List<int>();  for (int i = 0; i < iMaxLength; i++)//一共執行iMaxLength次,iMaxLength是元素的最大位元。  {  foreach (int number in arr)//分桶  {  currentItem = number.ToString();//將當前元素轉化成字串  try { currnetChar = currentItem[currentItem.Length-i-1]; }//從個位向高位開始分桶  catch { listArr[0].Add(number); continue; }//如果發生異常,則將該數壓入listArr[0]。比如說5 是沒有十位元的,執行上面的操作肯定會發生越界異常的,這正是期望的行為,我們認為5的十位元是0,所以將它壓入listArr[0]的桶裡。  switch (currnetChar)//通過currnetChar的值,確定它壓人哪個桶中。  {  case '0': listArr[0].Add(number); break;  case '1': listArr[1].Add(number); break;  case '2': listArr[2].Add(number); break;  case '3': listArr[3].Add(number); break;  case '4': listArr[4].Add(number); break;  case '5': listArr[5].Add(number); break;  case '6': listArr[6].Add(number); break;  case '7': listArr[7].Add(number); break;  case '8': listArr[8].Add(number); break;  case '9': listArr[9].Add(number); break;  default: throw new Exception("unknow error");  }  }  for (int j = 0; j < listArr.Length; j++)//將十個桶裡的資料重新排列,壓入list  foreach (int number in listArr[j].ToArray<int>())  {  list.Add(number);  listArr[j].Clear();//清空每個桶  }  arr = list.ToArray<int>();//arr指向重新排列的元素  //Console.Write("{0} times:",i);  Print(arr);//輸出一次排列的結果  list.Clear();//清空list  }  }  //得到最大元素的位元  private static int GetMaxLength(int[] arr)  {  int iMaxNumber = Int32.MinValue;  foreach (int i in arr)//遍曆得到最大值  {  if (i > iMaxNumber)  iMaxNumber = i;  }  return iMaxNumber.ToString().Length;//這樣獲得最大元素的位元是不是有點投機取巧了...  }  //輸出數組元素  public static void Print(int[] arr)  {  foreach (int i in arr)  System.Console.Write(i.ToString()+'\t');  System.Console.WriteLine();  }  //產生隨機數組。隨機數的範圍是0到1000。參數iLength指產生多少個隨機數  public static int[] CreateRandomArray(int iLength)  {  int[] arr = new int[iLength];  Random random = new Random();  for (int i = 0; i < iLength; i++)  arr[i] = random.Next(0,1001);  return arr;  }  }  }

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.