您的位置:首页 > 其它

快速排序,归并排序,堆排序,基数排序,插入排序,希尔排序,

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐