一、冒泡(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; } } }