10种排序

一、冒泡(Bubble)排序

[csharp]  view plain copy
  1. void BubbleSortArray()  
  2. {  
  3.       for(int i=1;i<n;i++)  
  4.       {  
  5.         for(int j=0;i<n-i;j++)  
  6.          {  
  7.               if(a[j]>a[j+1])//比较交换相邻元素  
  8.                {  
  9.                    int temp;  
  10.                    temp=a[j]; a[j]=a[j+1]; a[j+1]=temp;  
  11.                }  
  12.          }  
  13.       }  
  14. }  


二、选择排序

 

[cpp]  view plain copy
  1. void SelectSortArray()  
  2. {  
  3.     int min_index;  
  4.     for(int i=0;i<n-1;i++)  
  5.     {  
  6.          min_index=i;  
  7.          for(int j=i+1;j<n;j++)//每次扫描选择最小项  
  8.             if(arr[j]<arr[min_index])  min_index=j;  
  9.          if(min_index!=i)//找到最小项交换,即将这一项移到列表中的正确位置  
  10.          {  
  11.              int temp;  
  12.              temp=arr[i]; arr[i]=arr[min_index]; arr[min_index]=temp;  
  13. }  
  14. }  
  15. }  


 

三、插入排序

 

[cpp]  view plain copy
  1. void InsertSortArray()  
  2. {  
  3. for(int i=1;i<n;i++)//循环从第二个数组元素开始,因为arr[0]作为最初已排序部分  
  4. {  
  5.     int temp=arr[i];//temp标记为未排序第一个元素  
  6.     int j=i-1;  
  7. while (j>=0 && arr[j]>temp)/*将temp与已排序元素从小到大比较,寻找temp应插入的位置*/  
  8. {  
  9.     arr[j+1]=arr[j];  
  10.     j--;  
  11. }  
  12. arr[j+1]=temp;  
  13. }  
  14. }  


四、壳(Shell)排序

 

 

[cpp]  view plain copy
  1. void ShellSortArray()  
  2. {  
  3.   for(int incr=3;incr<0;incr--)//增量递减,以增量3,2,1为例  
  4. {  
  5.        for(int L=0;L<(n-1)/incr;L++)//重复分成的每个子列表  
  6. {  
  7.    for(int i=L+incr;i<n;i+=incr)//对每个子列表应用插入排序  
  8.    {  
  9.       int temp=arr[i];  
  10.       int j=i-incr;  
  11.       while(j>=0&&arr[j]>temp)  
  12.       {  
  13.           arr[j+incr]=arr[j];  
  14.           j-=incr;  
  15. }  
  16. arr[j+incr]=temp;  
  17. }  
  18. }  
  19. }  
  20. }  


五、归并排序五、归并排序

 

[cpp]  view plain copy
  1. void MergeSort(int low,int high)  
  2. {  
  3.    if(low>=high)   return;//每个子列表中剩下一个元素时停止  
  4.    else int mid=(low+high)/2;/*将列表划分成相等的两个子列表,若有奇数个元素,则在左边子列表大于右侧子列表*/  
  5.    MergeSort(low,mid);//子列表进一步划分  
  6.    MergeSort(mid+1,high);  
  7.    int [] B=new int [high-low+1];//新建一个数组,用于存放归并的元素  
  8.    for(int i=low,j=mid+1,k=low;i<=mid && j<=high;k++)/*两个子列表进行排序归并,直到两个子列表中的一个结束*/  
  9.    {  
  10.        if (arr[i]<=arr[j];)  
  11. {  
  12.     B[k]=arr[i];  
  13.     I++;  
  14. }  
  15. else  
  16.     { B[k]=arr[j]; j++; }  
  17. }  
  18. for(   ;j<=high;j++,k++)//如果第二个子列表中仍然有元素,则追加到新列表  
  19.       B[k]=arr[j];  
  20.    for(   ;i<=mid;i++,k++)//如果在第一个子列表中仍然有元素,则追加到新列表中  
  21.       B[k]=arr[i];  
  22.    for(int z=0;z<high-low+1;z++)//将排序的数组B的 所有元素复制到原始数组arr中  
  23.       arr[z]=B[z];  
  24. }  


六、快速排序

 

[cpp]  view plain copy
  1. int Partition(int [] arr,int low,int high)  
  2. {  
  3.     int pivot=arr[low];//采用子序列的第一个元素作为枢纽元素  
  4.     while (low < high)  
  5.     {  
  6.         //从后往前栽后半部分中寻找第一个小于枢纽元素的元素  
  7.         while (low < high && arr[high] >= pivot)  
  8.         {  
  9.             --high;  
  10.         }  
  11.         //将这个比枢纽元素小的元素交换到前半部分  
  12.         swap(arr[low], arr[high]);  
  13.         //从前往后在前半部分中寻找第一个大于枢纽元素的元素  
  14.         while (low <high &&arr [low ]<=pivot )  
  15.         {  
  16.             ++low ;  
  17.         }  
  18.         swap (arr [low ],arr [high ]);//将这个枢纽元素大的元素交换到后半部分  
  19.     }  
  20.     return low ;//返回枢纽元素所在的位置  
  21. }  
  22. void QuickSort(int [] a,int low,int high)  
  23. {  
  24.     if (low <high )  
  25.     {  
  26.         int n=Partition (a ,low ,high );  
  27.         QuickSort (a ,low ,n );  
  28.         QuickSort (a ,n +1,high );  
  29.     }  
  30. }  


 

七、堆排序

 

[cpp]  view plain copy
  1. void HeapSort(SeqIAst R)  
  2. {    //对R[1..n]进行堆排序,不妨用R[0]做暂存单元  
  3.     int I;  
  4.     BuildHeap(R); //将R[1-n]建成初始堆  
  5.     for(i=n;i>1;i--) //对当前无序区R[1..i]进行堆排序,共做n-1趟。  
  6.     {  
  7.         R[0]=R[1];  
  8.         R[1]=R[i];  
  9.         R[i]=R[0]; //将堆顶和堆中最后一个记录交换  
  10.         Heapify(R,1,i-1);  //将R[1..i-1]重新调整为堆,仅有R[1]可能违反堆性质  
  11.     }  
  12. }  


八、拓扑排序八、拓扑排序

 

[cpp]  view plain copy
  1. void TopologicalSort()/*输出拓扑排序函数。若G无回路,则输出G的顶点的一个拓扑序列并返回OK,否则返回ERROR*/  
  2. {  
  3.       int indegree[M];  
  4.       int i,k,j;  
  5.       char n;  
  6.       int count=0;  
  7.       Stack thestack;  
  8.       FindInDegree(G,indegree);//对各顶点求入度indegree[0....num]  
  9.       InitStack(thestack);//初始化栈  
  10.       for(i=0;i<G.num;i++)  
  11.           Console.WriteLine("结点"+G.vertices[i].data+"的入度为"+indegree[i]);  
  12.       for(i=0;i<G.num;i++)  
  13.       {  
  14.            if(indegree[i]==0)  
  15.               Push(thestack.vertices[i]);  
  16.       }  
  17.       Console.Write("拓扑排序输出顺序为:");  
  18.       while(thestack.Peek()!=null)  
  19.       {  
  20.                Pop(thestack.Peek());  
  21.                j=locatevex(G,n);  
  22.                if (j==-2)  
  23.                   {  
  24.                          Console.WriteLine("发生错误,程序结束。");  
  25.                          exit();  
  26.                   }  
  27.                 Console.Write(G.vertices[j].data);  
  28.                 count++;  
  29.                 for(p=G.vertices[j].firstarc;p!=NULL;p=p.nextarc)  
  30.                 {  
  31.                      k=p.adjvex;  
  32.                      if (!(--indegree[k]))  
  33.                          Push(G.vertices[k]);  
  34.                 }  
  35.       }  
  36.       if (count<G.num)  
  37.           Cosole.WriteLine("该图有环,出现错误,无法排序。");  
  38.       else  
  39.           Console.WriteLine("排序成功。");  
  40. }  


 

九、锦标赛排序(转)

[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include <math.h>  
  5. #define SIZE 100000  
  6. #define MAX 1000000  
  7. struct node  
  8. {  
  9.  long num;//关键字  
  10.  char str[10];  
  11.  int lastwin;//最后胜的对手  
  12.  int killer;//被击败的对手  
  13.  long times;//比赛次数  
  14. }data[SIZE];  
  15. long CompareNum=0;  
  16. long ExchangeNum=0;  
  17. long Read(char name[])//读取文件a.txt中的数据,并存放在数组data[]中;最后返回数据的个数  
  18. {  
  19.  FILE *fp;  
  20.  long i=1;  
  21.  fp=fopen(name,"rw");  
  22.  fscanf(fp,"%d%s",&data[i].num,data[i].str);  
  23.  while(!feof(fp))  
  24.  {  
  25.   i++;  
  26.   fscanf(fp,"%d%s",&data[i].num,data[i].str);  
  27.  }  
  28.  return (i-1);  
  29. }  
  30. long Create(long num)//创建胜者树,返回冠军(最小数)在数组data[]中的下标  
  31. {  
  32.  int i,j1,j2,max,time=1;  
  33.  long min;//记录当前冠军的下标  
  34.  for(i=1;pow(2,i-1)<num;i++)  
  35.   ;  
  36.  max=pow(2,i-1);//求叶子结点数目  
  37.  for(i=1;i<=max;i++)//初始化叶子结点  
  38.  {  
  39.   data[i].killer=0;  
  40.   data[i].lastwin=0;  
  41.   data[i].times=0;  
  42.   if(i>num)  
  43.    data[i].num=MAX;  
  44.  }  
  45.  for(i=1;i<=max;i+=2)//第一轮比赛  
  46.  {  
  47.   ++CompareNum;  
  48.   if(data[i].num <= data[i+1].num)  
  49.   {  
  50.    data[i].lastwin = i+1;  
  51.    data[i+1].killer=i;  
  52.    ++data[i].times;  
  53.    ++data[i+1].times;  
  54.    min=i;  
  55.   }  
  56.   else  
  57.   {  
  58.    data[i+1].lastwin=i;  
  59.    data[i].killer=i+1;  
  60.    ++data[i].times;  
  61.    ++data[i+1].times;  
  62.    min=i+1;  
  63.   }  
  64.  }  
  65.  j1=j2=0;//记录连续的两个未被淘汰的选手的下标  
  66.  while(time <= (log(max)/log(2)))//进行淘汰赛  
  67.  {  
  68.   for(i=1;i<=max;i++)  
  69.   {  
  70.    if(data[i].times==time && data[i].killer==0)//找到一名选手  
  71.    {  
  72.     j2=i;//默认其为两选手中的后来的  
  73.     if(j1==0)//如果第一位置是空的,则刚来的选手先来的  
  74.      j1=j2;  
  75.     else//否则刚来的选手是后来的,那么选手都已到场比赛开始  
  76.     {  
  77.      ++CompareNum;  
  78.      if(data[j1].num <= data[j2].num)//先来的选手获胜  
  79.      {  
  80.       data[j1].lastwin = j2;//最后赢的是j2  
  81.       data[j2].killer=j1;//j2是被j1淘汰的  
  82.       ++data[j1].times;  
  83.       ++data[j2].times;//两选手场次均加1  
  84.       min=j1;//最小数下标为j1  
  85.       j1=j2=0;//将j1,j2置0  
  86.      }  
  87.      else//同理  
  88.      {  
  89.       data[j2].lastwin=j1;  
  90.       data[j1].killer=j2;  
  91.       ++data[j1].times;  
  92.       ++data[j2].times;  
  93.       min=j2;  
  94.       j1=j2=0;  
  95.      }  
  96.     }  
  97.    }  
  98.   
  99.   }  
  100.   time++;//轮数加1  
  101.  }  
  102.  return min;//返回冠军的下标  
  103. }  
  104. void TournamentSort(long num)//锦标赛排序  
  105. {  
  106.  long tag=Create(num);//返回最小数下标  
  107.  FILE *fp1;  
  108.  fp1=fopen("sort.txt","w+");//为写入创建并打开文件sort.txt  
  109.  while(data[tag].num != MAX)//当最小值不是无穷大时  
  110.  {  
  111.   printf("%d %s\n",data[tag].num,data[tag].str);//输出数据  
  112.   fprintf(fp1,"%d %s\n",data[tag].num,data[tag].str);//写入数据  
  113.   data[tag].num=MAX;//将当前冠军用无穷大替换  
  114.   tag=Create(num);//返回下一个冠军的下标  
  115.  }  
  116. }  
  117. int main()  
  118. {  
  119.  int num;  
  120.  char name[10];  
  121.  printf("Input name of the file:");  
  122.  gets(name);  
  123.  num=Read(name);//读文件  
  124.  TournamentSort(num);//锦标赛排序  
  125.  printf("CompareNum=%d\nExchangeNum=%d\n",CompareNum,ExchangeNum);  
  126.  return 0;  
  127. }  


十、基数排序

十、基数排序(转 C#)

[csharp]  view plain copy
  1. using System;  
  2.   using System.Collections.Generic;  
  3.   using System.Linq;  
  4.   using System.Text;  
  5.   namespace LearnSort  
  6.   {  
  7.   class Program  
  8.   {  
  9.   static void Main(string[] args)  
  10.   {  
  11.   int[] arr = CreateRandomArray(10);//产生随机数组  
  12.   Print(arr);//输出数组  
  13.   RadixSort(ref arr);//排序  
  14.   Print(arr);//输出排序后的结果  
  15.   Console.ReadKey();  
  16.   }  
  17.   public static void RadixSort(ref int[] arr)  
  18.   {  
  19.   int iMaxLength = GetMaxLength(arr);  
  20.   RadixSort(ref arr, iMaxLength);  
  21.   }  
  22.   private static void RadixSort(ref int[] arr, int iMaxLength)  
  23.   {  
  24.   List<int> list = new List<int>();//存放每次排序后的元素  
  25.   List<int>[] listArr = new List<int>[10];//十个桶  
  26.   char currnetChar;//存放当前的字符比如说某个元素123 中的2  
  27.   string currentItem;//存放当前的元素比如说某个元素123  
  28.   for (int i = 0; i < listArr.Length; i++)//给十个桶分配内存初始化。  
  29.   listArr[i] = new List<int>();  
  30.   for (int i = 0; i < iMaxLength; i++)//一共执行iMaxLength次,iMaxLength是元素的最大位数。  
  31.   {  
  32.   foreach (int number in arr)//分桶  
  33.   {  
  34.   currentItem = number.ToString();//将当前元素转化成字符串  
  35.   try { currnetChar = currentItem[currentItem.Length-i-1]; }//从个位向高位开始分桶  
  36.   catch { listArr[0].Add(number); continue; }//如果发生异常,则将该数压入listArr[0]。比如说5 是没有十位数的,执行上面的操作肯定会发生越界异常的,这正是期望的行为,我们认为5的十位数是0,所以将它压入listArr[0]的桶里。  
  37.   switch (currnetChar)//通过currnetChar的值,确定它压人哪个桶中。  
  38.   {  
  39.   case '0': listArr[0].Add(number); break;  
  40.   case '1': listArr[1].Add(number); break;  
  41.   case '2': listArr[2].Add(number); break;  
  42.   case '3': listArr[3].Add(number); break;  
  43.   case '4': listArr[4].Add(number); break;  
  44.   case '5': listArr[5].Add(number); break;  
  45.   case '6': listArr[6].Add(number); break;  
  46.   case '7': listArr[7].Add(number); break;  
  47.   case '8': listArr[8].Add(number); break;  
  48.   case '9': listArr[9].Add(number); break;  
  49.   defaultthrow new Exception("unknow error");  
  50.   }  
  51.   }  
  52.   for (int j = 0; j < listArr.Length; j++)//将十个桶里的数据重新排列,压入list  
  53.   foreach (int number in listArr[j].ToArray<int>())  
  54.   {  
  55.   list.Add(number);  
  56.   listArr[j].Clear();//清空每个桶  
  57.   }  
  58.   arr = list.ToArray<int>();//arr指向重新排列的元素  
  59.   //Console.Write("{0} times:",i);  
  60.   Print(arr);//输出一次排列的结果  
  61.   list.Clear();//清空list  
  62.   }  
  63.   }  
  64.   //得到最大元素的位数  
  65.   private static int GetMaxLength(int[] arr)  
  66.   {  
  67.   int iMaxNumber = Int32.MinValue;  
  68.   foreach (int i in arr)//遍历得到最大值  
  69.   {  
  70.   if (i > iMaxNumber)  
  71.   iMaxNumber = i;  
  72.   }  
  73.   return iMaxNumber.ToString().Length;//这样获得最大元素的位数是不是有点投机取巧了...  
  74.   }  
  75.   //输出数组元素  
  76.   public static void Print(int[] arr)  
  77.   {  
  78.   foreach (int i in arr)  
  79.   System.Console.Write(i.ToString()+'\t');  
  80.   System.Console.WriteLine();  
  81.   }  
  82.   //产生随机数组。随机数的范围是0到1000。参数iLength指产生多少个随机数  
  83.   public static int[] CreateRandomArray(int iLength)  
  84.   {  
  85.   int[] arr = new int[iLength];  
  86.   Random random = new Random();  
  87.   for (int i = 0; i < iLength; i++)  
  88.   arr[i] = random.Next(0,1001);  
  89.   return arr;  
  90.   }  
  91.   }  
  92.   }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值