8种排序算法

来源:互联网 发布:霍去病怎么死的 知乎 编辑:程序博客网 时间:2024/05/17 23:32
// Temp.cpp : 定义控制台应用程序的入口点。//#include"stdafx.h"#define BestInsertSortLength 16#define Swap(a,b)  (a)^=(b)^=(a)^=(b); #include<fstream>#include<iostream>#include<time.h>#include<windows.h>#include<WinBase.h>using namespace std; inline unsigned __int64 GetCPUTickCount(){ _asm{rdtsc;}}//输出void Output(int *& arr,int num,ofstream &cout){for(int i=0;i<num;i++){cout<<arr[i]<<"  ";}cout<<endl;}//选择排序void SelectSort(int * & arr,int left,int right){ for(int i=left;i<=right;i++){int max=arr[left];int index=left;for(int j=left;j<=right-i;j++){if(arr[j]>max){index=j;max=arr[j];}}if(index!=right-i)Swap(arr[index],arr[right-i]);}}//插入排序void InsertSort(int *&arr,int left,int right){for(int i=left;i<=right;i++){int j=i-1;while(j>=0&&arr[j]>arr[j+1]){Swap(arr[j],arr[j+1]);j--;}}}//冒泡排序void BubbleSort(int *&arr,int num){      for(int i=0;i<num;i++)     {     bool flag=false;             for(int j=0;j<num-i-1;j++)             {                     if(arr[j]>arr[j+1])                     {                           Swap(arr[j],arr[j+1]);                           flag=true;                                  }             }             if(flag==false)             return ;     }}//快速排序int Patition(int *&arr,int left,int right){ int piviotElement=arr[left]; int piviot=left; int low=left+1; int high=right; while(low<high) { while(low<high&&arr[low]<piviotElement) { low++; } while(high>low&&arr[high]>piviotElement) { high--;  } if(low<high) {Swap(arr[low],arr[high]);low++;high--; } else { break; } } if(arr[low]>arr[piviot]) { if(low-1!=piviot)Swap(arr[low-1],arr[piviot]); return low-1; } else { if(low!=piviot)Swap(arr[low],arr[piviot]); } return low;}void QuickSort(int *&arr,int left,int right){if(left>=right)return;     int piviot=Patition(arr,left,right);  QuickSort(arr,left,piviot-1); QuickSort(arr,piviot+1,right);}/*//归并排序void Merge(int *&arr,int *& sav,int left,int right,int mid){       int i;     for( i=left;i<=right;i++)     {        sav[i]=arr[i];             }           i=left;     int j=mid+1;     int index=left;     while(i<=mid&&j<=right)     {         if(sav[i]>sav[j])         {            arr[index++]=sav[j++];                      }         else         {             arr[index++]=sav[i++];         }                        }     while(i<=mid)     {        arr[index++]=sav[i++];     }                while(j<=right)        {              arr[index++]=sav[j++];              }          }void MergeSort(int *&arr,int *&sav,int left,int right){     if(right-left<=0)return;           int mid=(left+right)/2;     MergeSort(arr,sav,left,mid);     MergeSort(arr,sav,mid+1,right);     Merge(arr,sav,left,right,mid);}*///改进的归并算法 /*改进:  1,n<=16时用插入排序  2,通过一个变量来记录第几次做merge时,应该从哪个数组copy数据到哪个数组;从而减少A,B数组之间来回copy数据  3,不用递归  即用迭代来替换递归  */  void Merge(int *&arr,int *& sav,int left,int right,int mid){    //  if(right-left<=1)return; if(right<mid) {/* for(int i=left;i<=right;i++) { arr[i]=sav[i]; }*/ memcpy(arr+left,sav+left,sizeof(int)*(right-left+1)); return ; }        int i=left;     int j=mid;     int index=left;     while(i<mid&&j<=right)     {         if(sav[i]>sav[j])         {            arr[index++]=sav[j++];           }         else         {             arr[index++]=sav[i++];         }                        }     while(i<mid)     {        arr[index++]=sav[i++];     }                while(j<=right)        {              arr[index++]=sav[j++];            } }void MergeSort(int *&arr,int left,int right){if(arr==NULL) return;if(right<=left)return; //空数组int index=left;while(index+BestInsertSortLength<=right){InsertSort(arr,index,index+BestInsertSortLength);index=index+BestInsertSortLength+1;}InsertSort(arr,index,right); int *sav=new int[right-left+1];int mergeNum=1;for(;; mergeNum++){index=left;while(index+2*mergeNum*BestInsertSortLength+1<=right){if(mergeNum%2==1){Merge(sav,arr,index,index+2*mergeNum*BestInsertSortLength+1,index+mergeNum*BestInsertSortLength+1);}else{  Merge(arr,sav,index,index+2*mergeNum*BestInsertSortLength+1,index+mergeNum*BestInsertSortLength+1);}index=index+2*mergeNum*BestInsertSortLength+1;}  if(mergeNum%2==1){ Merge(sav,arr,index,right,index+mergeNum*BestInsertSortLength+1);}else{  Merge(arr,sav,index,right,index+mergeNum*BestInsertSortLength+1);}  if(left+2*mergeNum*BestInsertSortLength+1>=right)  break;}if(mergeNum%2==1){for(int i=left;i<=right;i++){arr[i]=sav[i];}} }//堆排序void FixHeap(int *&arr,int start,int num) //调整堆{int i=start;int j=2*i+1;    while(j<=num){if(j<num&&arr[j]<arr[j+1]){j++;}if(arr[i]<arr[j]){Swap(arr[i],arr[j]);i=j;j=2*i+1;}else{break;}}  }void HeapSort(int *&arr,int num){if(num<=1)return ;for(int i=(num-2)/2;i>=0;i--){ FixHeap(arr,i,num-1);}while(num-->=1){       if(num!=0)Swap(arr[0],arr[num]);FixHeap(arr,0,num-1);}}//基数排序用到的数据const int Barrel_Num=10;  //分为几个桶int barrels[Barrel_Num];  //各个桶struct Element            //暂时存放元素的静态链表{int data;int next;Element(){next=-1;}int getDigit(int index) //得到data第index位的数字{int temp=data;for(int i=index;i>1;i--){temp=temp/10;}return temp%10;}};//基数排序//@param//arr 待排序数组//left 待排序数组的起始下标//right 待排序数组的终止下标//currentDepth 当前位 一开始为1//maxDepth  最大位  由要排序数组中的最大元素的位数决定void RadixSort(int *&arr,int left,int right,int currentDepth,int maxDepth){if(currentDepth>maxDepth)return;  //超过最大位 结束memset(barrels,-1,sizeof(int)*Barrel_Num);Element *ele=new Element[right-left+1];for(int i=right;i>=left;i--)  //倒着依次装入桶中{int j=right-i;ele[j].data=arr[i];int temp=ele[j].getDigit(currentDepth);if(barrels[temp]==-1){barrels[temp]=j;}else{ele[j].next=barrels[temp];barrels[temp]=j;}}//顺序依次取出桶中的元素int count=left;for(int i=0;i<Barrel_Num;i++){int temp=barrels[i];while(temp!=-1){arr[count]=ele[temp].data;temp=ele[temp].next;count++;}}delete []ele;RadixSort(arr,left,right,currentDepth+1,maxDepth);}//希尔排序void ShellSort(int * & arr,int num){int gap=num;do{gap=gap/3+1;for(int i=0;i<gap;i++){for(int j=i+gap;j<num;j+=gap){int k=j-gap;while(k>=0&&arr[k]>arr[k+gap]){Swap(arr[k],arr[k+gap]);k-=gap;}}}}while(gap>1);}int main(){ofstream cout("output.txt");srand((unsigned int)time(0)); int n=rand()%5000+5000; int *arr =new int [n];int *forSort=new int[n];  for(int i=0;i<n;i++)  {      forSort[i]=rand()%1000000;  }    memcpy(arr,forSort,sizeof(int)*n);cout<<"未排序:"<<endl;Output(arr,n,cout); unsigned __int64 startTime;unsigned __int64 finishTime; startTime=GetCPUTickCount();   SelectSort(arr,0,n-1);     finishTime=GetCPUTickCount();   cout<<"选择排序:"<<endl;   cout<<"用时:"<<finishTime-startTime<<"个CPU周期"<<endl;   Output(arr,n,cout);       memcpy(arr,forSort,sizeof(int)*n);      startTime=GetCPUTickCount();   InsertSort(arr,0,n-1 );   finishTime=GetCPUTickCount();      cout<<"插入排序:"<<endl;   cout<<"用时:"<<finishTime-startTime<<"个CPU周期"<<endl;   Output(arr,n,cout);      memcpy(arr,forSort,sizeof(int)*n);       startTime=GetCPUTickCount();  BubbleSort(arr,n);   finishTime=GetCPUTickCount();  cout<<"冒泡排序:"<<endl;  cout<<"用时:"<<finishTime-startTime<<"个CPU周期"<<endl;  Output(arr,n,cout);    memcpy(arr,forSort,sizeof(int)*n);   startTime=GetCPUTickCount();  MergeSort(arr,0,n-1); finishTime=GetCPUTickCount();    cout<<"归并排序:"<<endl;   cout<<"用时:"<<finishTime-startTime<<"个CPU周期"<<endl;   Output(arr,n,cout);   memcpy(arr,forSort,sizeof(int)*n);     startTime=GetCPUTickCount();QuickSort(arr,0,n-1);finishTime=GetCPUTickCount();cout<<"快速排序:"<<endl;   cout<<"用时:"<<finishTime-startTime<<"个CPU周期"<<endl; Output(arr,n,cout); memcpy(arr,forSort,sizeof(int)*n);startTime=GetCPUTickCount(); HeapSort(arr,n);finishTime=GetCPUTickCount();cout<<"堆排序:"<<endl;  cout<<"用时:"<<finishTime-startTime<<"个CPU周期"<<endl;Output(arr,n,cout); memcpy(arr,forSort,sizeof(int)*n);          startTime=GetCPUTickCount();     ShellSort(arr,n);    finishTime=GetCPUTickCount();        cout<<"希尔排序:"<<endl;    cout<<"用时:"<<finishTime-startTime<<"个CPU周期"<<endl;Output(arr,n,cout); startTime=GetCPUTickCount();    RadixSort(arr,0,n-1,1,6);finishTime=GetCPUTickCount();cout<<"基数排序:"<<endl;    cout<<"用时:"<<finishTime-startTime<<"个CPU周期"<<endl;Output(arr,n,cout);      system("pause");return 0;}