快速排序,归并排序,堆排序,基数排序,插入排序,希尔排序,
2012-09-09 16:28
525 查看
#include "stdafx.h" // 排序.cpp : 定义控制台应用程序的入口点。 #include<windows.h> #include<iostream> #include<stack> //#include<stdlib.h> #include<ctime> using namespace std; LARGE_INTEGER BegainTime ; LARGE_INTEGER EndTime ; LARGE_INTEGER Frequency ; void ShellSort(int *Array, int n); void swap(double &a,double &b) { double tmp; tmp=a; a=b; b=tmp; } void print(double *a,double n) { int i; for(i=0;i<n;i++) cout<<a[i]<<'\t'; cout<<endl; } void BubbleSort(double *arr,double n) { for(int i=0;i<n-1;i++) for(int j=1;j<n-i;j++) if(arr[j-1]>arr[j]) swap(arr[j-1],arr[j]); } int maxbit(int *arr,int n)//求位数 { int d=1; int p=10; for(int i=0;i<n;++i) while(arr[i]>=p)//巧妙的求出了最高的的位数 { p=p*10; ++d; } return d; } void RadixSort(int *arr,int n)//④基数排序 采用非链表的方式 有点类似 计数排序 { int d=maxbit(arr,n); int *tmp=new int ; int *count=new int[10];//计数器记录0-9之间的每个位数的个数 int i,j,k; int radix=1; for(i=1;i<=d;i++)//进行d次排序 { for(j=0;j<10;j++) count[j]=0; for(j=0;j<n;j++) { k=(arr[j]/radix)%10;//统计个数 count[k]++; } for(j=1;j<10;j++) count[j]=count[j-1]+count[j];//解释一下比如count[4]=5现在表示的是当前位上是1、2、3、4的有5个。方法非常巧妙!!! for(j=n-1;j>=0;j--) { k=(arr[j]/radix)%10; count[k]--;//count存放的是个数,从第一个开始,要转化为数组坐标, tmp[count[k]]=arr[j];//这一步最关键找到每一个元素对应的新位置, } for(j=0;j<n;j++) arr[j]=tmp[j]; radix=radix*10; } delete [] tmp; delete [] count; } void InsertSort(double *Array, int n)//maybe the best { int i,j; double temp; for(i=1;i<n;i++) { temp=Array[i]; for(j=i-1;j>=0&&temp<Array[j];j--) { Array[j+1]=Array[j]; } if(j+1!=i)Array[j+1]=temp; } } /*直接插入排序复杂度分析 从空间复杂度上来看,它只需要一个记录的辅助空间。因此关键是看它的时间复杂度。 当最好的情况,也就是要排序的表本身就是有序的,那么我们共比较了 n-1次,因此没有移动的记录,时间复杂度为O(n)。 当最坏的情况,即待排序表是逆序的情况比如{9,8,7,6,5,4,3,2,1,0},此时需要比较 2+3+..+n次,而记录的移次数也达到最大值 3+4+5+..+n+1次。 如果排序记录是随机的,那么根据概率相同的原则,平均比较和移动次约为n*n/4 次。 因此,我们得出直接插入排序法的时间复杂度为O(n2)。从这里也看出,同样的O(n2)时间复杂度,直接插入排序法比冒泡和简单选择排序的性能要好一些。*/ void ShellSort(double *Array, int n) { int i,j,k,step; double temp; for(step=n/2;step>=1;step=step/2) { for(i=step;i<2*step;i++) { for(j=i;j<n;j=j+step) { temp=Array[j]; for(k=j-step;k>=0&&temp<Array[k];k=k-step) { Array[k+step]=Array[k]; } if(k+step!=j) Array[k+step]=temp; } } } } void SelectSort(double *Array, int n) { int i,j,small; double temp; for(i=0;i<n-1;i++)//每次选一个最小的放在i位置 { small=i;//k用来标记当前最小的 for(j=i+1;j<n;j++) { if(Array[j]<Array[small]) small=j; } if(small != i) { temp = Array[i]; Array[i] = Array[small]; Array[small] = temp; } } } /*直接选择时间复杂度:第1次排序要进行 n-1 次比较,第2次排序要进行 n-2 次比较,... ,第 n-1 次排序要进行1次比较,所以总的比较次数为: 比较次数 = (n-1) + (n-2) + ... + 1 = n(n-1)/2 在各次排序中,数据元素的移动次数最好为0次,最坏为3次。所以总的移动次数最好为0次,最坏为 3(n-1) 次。因此,直接选择排序算法的时间复杂度为 O (n^2) 。*/ int part_mid(double *arr,int low,int high) { double key=arr[low]; while(low<high) { while(low<high&&arr[high]>=key) high--; arr[low]=arr[high]; while(low<high&&arr[low]<=key) low++; arr[high]=arr[low]; } arr[low]=key; return low; } void QuickSort(double *arr,int low,int high) { int mid; if(low<high) { //只有大于1时才排序,没有这句可能引起数组越界 mid=part_mid(arr,low,high); QuickSort(arr,low,mid-1); QuickSort(arr,mid+1,high); } } void QuickSort2(double *arr,int low,int high)//非递归 { stack<int> st; if(low<high) { int mid=part_mid(arr,low,high); if(low<mid-1) { st.push(low); st.push(mid-1); } if(mid+1<high) { st.push(mid+1); st.push(high); } //其实就是用栈保存每一个待排序子串的首尾元素下标,下一次while循环时取出这个范围,对这段子序列进行partition操作 while(!st.empty()) { int q=st.top(); st.pop(); int p=st.top(); st.pop(); mid=part_mid(arr,p,q); if(p<mid-1) { st.push(p); st.push(mid-1); } if(mid+1<q) { st.push(mid+1); st.push(q); } } } } void merge(double *arr,int low,int mid,int high) { double *temp= new double [high-low+1]; int i=low,j=mid+1,k=0; while(i<=mid&&j<=high) { if(arr[i]>arr[j]) { temp[k]=arr[j]; j++; } else { temp[k]=arr[i]; i++; } k++; } while(i<=mid) { temp[k++]=arr[i++]; } while(j<=high) { temp[k++]=arr[j++]; } for(i=low,j=0;i<=high;i++,j++) arr[i]=temp[j]; } void MergeSort(double *arr,int low,int high) { if(low<high) { int mid=(low+high)/2; MergeSort(arr,low,mid); MergeSort(arr,mid+1,high); merge(arr,low,mid,high); } } void AdjustHeap(double *arr, int r, int m)// 调整arr[r...m]为大跟堆,r+1到m为有序 调整时 堆数组从1开始 { double temp; if(r==0) return;//堆数组不能从零开始 temp = arr[r]; for(int j=2*r;j<=m;j*=2) { if((j+1<=m)&&(arr[j]<arr[j+1])) j++; if(arr[r]>=arr[j]) break; arr[r] = arr[j]; arr[j] = temp; r = j; } } void HeapSort(double *arr, int n) //假设堆数组从1开始存储 n表示b的长度 b【0...n-1】 其中b[1..n-1]存储要处理的数据 { for(int i=(n-1)/2;i>0;i--)//construct the heap AdjustHeap(arr,i,n-1); /*for(int k=1;k<n;k++) cout<<arr[k]<<" "; cout<<endl;*/ for(int j=n-1;j>1;j--) { swap(arr[1],arr[j]); AdjustHeap(arr,1,j-1); } } int _tmain(int argc, _TCHAR* argv[]) { int n; double *a,*b;//a[5]; double time[100]; double sum_s=0; double average; cout<<"输入数据个数:"; cin>>n; a=new double ; b=new double [n+1]; int *ra= new int ; for(int i=0;i<n;i++) {a[i]=rand()%100;ra[i]=(int)a[i];} int flag=1,j=0,ij=0; //cout<<"0,exit;1,insert;2,quick;3,select;4,bubble;5,shell;6,radix;7,morge;8,heap"<<endl; while(flag!=0) { cout<<"0,exit;1,insert;2,quick;3,select;4,bubble;5,shell;6,radix;7,morge;8,heap"<<endl; print(a,n);// cin>>flag; switch(flag) { case 0: flag=0;break; case 1: cout<<"insert sort"<<endl; for(j=0;j<100;j++) { QueryPerformanceFrequency(&Frequency); QueryPerformanceCounter(&BegainTime) ; //? insert_sort(a,n); //FindEulerCircuit(G); InsertSort(a,n); QueryPerformanceCounter(&EndTime); //cout<<"程序运行时间(单位:s): "<<(double)( EndTime.QuadPart-BegainTime.QuadPart )/ Frequency.QuadPart <<endl; time[j]=(double)( EndTime.QuadPart-BegainTime.QuadPart )/ Frequency.QuadPart; sum_s=sum_s+time[j]; } average=sum_s/100; cout<<"程序运行100次平均时间为:"<<average<<endl; //print(a,n); break; case 2: cout<<"quick sort"<<endl; for(j=0;j<100;j++) { QueryPerformanceFrequency(&Frequency); QueryPerformanceCounter(&BegainTime) ; //quick_sort(a,0,n-1); // QuickSort(a,0,n-1);//////////////////////////////////////////////////////////////////// QueryPerformanceCounter(&EndTime); //cout<<"程序运行时间(单位:s): "<<(double)( EndTime.QuadPart-BegainTime.QuadPart )/ Frequency.QuadPart <<endl; time[j]=(double)( EndTime.QuadPart-BegainTime.QuadPart )/ Frequency.QuadPart; sum_s=sum_s+time[j]; } average=sum_s/100; cout<<"程序运行100次平均时间为:"<<average<<endl; //print(a,n); break; case 3: cout<<"select sort"<<endl; for(j=0;j<100;j++) { QueryPerformanceFrequency(&Frequency); QueryPerformanceCounter(&BegainTime) ; //select_sort(a,n); SelectSort(a,n); QueryPerformanceCounter(&EndTime); //cout<<"程序运行时间(单位:s): "<<(double)( EndTime.QuadPart-BegainTime.QuadPart )/ Frequency.QuadPart <<endl; time[j]=(double)( EndTime.QuadPart-BegainTime.QuadPart )/ Frequency.QuadPart; sum_s=sum_s+time[j]; } average=sum_s/100; cout<<"程序运行100次平均时间为:"<<average<<endl; //print(a,n); break; case 4: cout<<"bubble sort"<<endl; for(j=0;j<100;j++) { QueryPerformanceFrequency(&Frequency); QueryPerformanceCounter(&BegainTime) ; //bubble_sort(a,n); //FindEulerCircuit(G); BubbleSort(a,n); QueryPerformanceCounter(&EndTime); //cout<<"程序运行时间(单位:s): "<<(double)( EndTime.QuadPart-BegainTime.QuadPart )/ Frequency.QuadPart <<endl; time[j]=(double)( EndTime.QuadPart-BegainTime.QuadPart )/ Frequency.QuadPart; sum_s=sum_s+time[j]; } average=sum_s/100; cout<<"程序运行100次平均时间为:"<<average<<endl; //print(a,n); break; case 5: cout<<"shell sort"<<endl; for(j=0;j<100;j++) { QueryPerformanceFrequency(&Frequency); QueryPerformanceCounter(&BegainTime) ; ShellSort(a,n);//shell_sort(a,n);//FindEulerCircuit(G); // this call has a problem QueryPerformanceCounter(&EndTime); //cout<<"程序运行时间(单位:s): "<<(double)( EndTime.QuadPart-BegainTime.QuadPart )/ Frequency.QuadPart <<endl; time[j]=(double)( EndTime.QuadPart-BegainTime.QuadPart )/ Frequency.QuadPart; sum_s=sum_s+time[j]; } average=sum_s/100; cout<<"程序运行100次平均时间为:"<<average<<endl; //print(a,n); break; case 6: cout<<"radix sort"<<endl; for(j=0;j<100;j++) { QueryPerformanceFrequency(&Frequency); QueryPerformanceCounter(&BegainTime) ; for(int i=0;i<n;i++) ra[i]=(int)a[i]; RadixSort(ra,n);//? for(int i=0;i<n;i++) a[i]=ra[i]; QueryPerformanceCounter(&EndTime); //cout<<"程序运行时间(单位:s): "<<(double)( EndTime.QuadPart-BegainTime.QuadPart )/ Frequency.QuadPart <<endl; time[j]=(double)( EndTime.QuadPart-BegainTime.QuadPart )/ Frequency.QuadPart; sum_s=sum_s+time[j]; } average=sum_s/100; cout<<"程序运行100次平均时间为:"<<average<<endl; //print(a,n); break; case 7: cout<<"morge sort"<<endl; for(j=0;j<100;j++) { QueryPerformanceFrequency(&Frequency); QueryPerformanceCounter(&BegainTime) ; MergeSort(a,0,n-1);//?why注意///////////////////////////////////////////////////////////////////////////////////////////////////?????????? QueryPerformanceCounter(&EndTime); //cout<<"程序运行时间(单位:s): "<<(double)( EndTime.QuadPart-BegainTime.QuadPart )/ Frequency.QuadPart <<endl; time[j]=(double)( EndTime.QuadPart-BegainTime.QuadPart )/ Frequency.QuadPart; sum_s=sum_s+time[j]; } average=sum_s/100; cout<<"程序运行100次平均时间为:"<<average<<endl; print(a,n); break; case 8: cout<<"heap sort"<<endl; for(j=0;j<100;j++) { QueryPerformanceFrequency(&Frequency); QueryPerformanceCounter(&BegainTime) ; for(int ij=0;ij<n;ij++) b[ij+1]=a[ij]; HeapSort(b,n+1); for(int ij=0;ij<n;ij++) a[ij]=b[ij+1]; QueryPerformanceCounter(&EndTime); time[j]=(double)( EndTime.QuadPart-BegainTime.QuadPart )/ Frequency.QuadPart; sum_s=sum_s+time[j]; } average=sum_s/100; cout<<"程序运行100次平均时间为:"<<average<<endl; //print(a,n); break; default : cout<<"invalidate input"<<endl; } print(a,n); } return 0; }
相关文章推荐
- 插入排序、冒泡排序、选择排序、希尔排序、快速排序、归并排序、堆排序和LST基数排序——C++实现
- 归并排序,堆排序,基数排序,希尔排序,快速排序,交换排序,选择排序和插入排序的总结和比较
- C# 插入排序 冒泡排序 选择排序 快速排序 堆排序 归并排序 基数排序 希尔排序
- 各种排序算法总结----基数排序、归并排序、插入排序、冒泡排序、选择排序、快速排序、堆排序、希尔排序
- 经典排序算法设计与分析(插入排序、冒泡排序、选择排序、shell排序、快速排序、堆排序、分配排序、基数排序、桶排序、归并排序)
- 排序方法了解一下(冒泡排序、选择排序、堆排序、插入排序、希尔排序、归并排序、快速排序、基数排序)
- 数据结构-排序算法详解(插入排序,希尔排序,堆排序,归并排序,快速排序,桶式排序)
- 快速排序、希尔排序、插入排序、选择排序、归并排序、堆排序总结
- 七大内部排序算法总结(插入排序、希尔排序、冒泡排序、简单选择排序、快速排序、归并排序、堆排序)
- 排序算法合集(插入排序,折半插入排序,希尔排序,冒泡排序,快速排序,简单选择排序,堆排序,归并排序)
- 选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序
- 插入排序、二分插入排序、希尔排序、选择排序、冒泡排序、鸡尾酒排序、快速排序、堆排序、归并排序
- 各种排序算法实现——基数排序、归并排序、插入排序、冒泡排序、选择排序、快速排序、堆排序、希尔排序
- 七大内部排序算法总结(插入排序、希尔排序、冒泡排序、简单选择排序、快速排序、归并排序、堆排序)
- 基本排序算法(冒泡排序 选择排序 插入排序 快速排序 归并排序 基数排序 希尔排序)
- 快速排序,插入排序,归并排序,计数排序,基数排序,堆排序
- 七大内部排序算法总结(插入排序、希尔排序、冒泡排序、简单选择排序、快速排序、归并排序、堆排序)
- 选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序是稳定的排序算法。
- 【程序员笔试面试必会——排序①】Python实现 冒泡排序、选择排序、插入排序、归并排序、快速排序、堆排序、希尔排序
- C# 插入排序 冒泡排序 选择排序 高速排序 堆排序 归并排序 基数排序 希尔排序