数据结构的课设,我选择了划水摸鱼,选择了最简单的排序算法性能比较,设计了希尔排序,冒泡排序,选择排序,插入排序,快速排序,希尔排序在老师的要求下,选择了三种增量,进行对比。
#include<iostream>
#include<cstdlib>
#include<algorithm>
using namespace std;
int temp[1010],n,temp2[1010],sum1[7],sum2[7],index=0;
int select_sort(int a[],int n)
{
cout<<"选择排序前为:\n";
int count1=0,count2=0; //count1记录比较次数,count2记录赋值次数
for(int i=0;i<n;i++) //将随机生成的数组a[n]赋值给temp[n]
{
temp[i]=a[i];
cout<<a[i]<<" ";
}
cout<<endl;
int i,j,index;
for(i=0;i<n-1;i++) // 一共需要进行n-1次排序
{
index=i;
for(j=i+1;j<n;j++) //找到查询区域内最小元素的位置
{
if(temp[j]<temp[index])
{
index=j;
count1++;
}
}
if(index!=i) // 若index与i不同,发生交换
{
count2++;
swap(temp[index],temp[i]);
}
}
cout<<"选择排序后为:\n";
for(int i=0;i<n;i++)cout<<temp[i]<<" ";
cout<<endl;
cout<<"选择排序比较次数为 "<<count1<<" 赋值次数为"<<count2<<endl;
sum1[0]=count1;
sum2[0]=count2;
}
int bubble_sort(int a[],int n)
{
cout<<"冒泡排序前为:\n";
int count1=0,count2=0;
for(int i=0;i<n;i++)
{
cout<<a[i]<<" ";
temp[i]=a[i];
}
cout<<endl;
for(int i=0;i<n-1;i++) // 一共需要进行n-1次排序
{
for(int j=0;j<n-1-i;j++)//从0到n-i-1进行比较
{
if(temp[j]>temp[j+1])
{
swap(temp[j],temp[j+1]);
count2++;
count1++;
}
}
}
cout<<"冒泡排序后为:\n";
for(int i=0;i<n;i++)
{
cout<<temp[i]<<" ";
}
cout<<endl;
cout<<"冒泡排序比较次数为 "<<count1<<" 赋值次数为"<<count2<<endl;
sum1[1]=count1;
sum2[1]=count1;
}
int init1(int a[]) //cnt1记录比较次数,cnt2记录赋值次数
{
printf("快速排序前为\n");
for(int i=0;i<n;i++)
{
temp[i]=a[i];
cout<<temp[i]<<" ";
}
cout<<endl;
}
int cnt1=0,cnt2=0;
void quick_sort(int temp[],int l,int r)
{
if(l>=r)return;
int x=temp[(l+r)>>1]; //选取基准量
int i=l-1,j=r+1;
while(i<j)
{
do
{
i++;
cnt1++;
}while(temp[i]<x); // 若temp[i]<x,则i指针后移
do
{
j--;
cnt1++;
}while(temp[j]>x); //若temp[i]>x,则j指针前移
if(i<j) //交换temp[i],temp[j]
{
swap(temp[i],temp[j]);
cnt2++;
}
}
quick_sort(temp,l,j);
quick_sort(temp,j+1,r);
}
print_quick_sort()
{
printf("快速排序后为:\n");
for(int i=0;i<n;i++)cout<<temp[i]<<" ";
cout<<endl;
cout<<"快速排序比较次数为 "<<cnt1<<" 赋值次数为"<<cnt2<<endl;
sum1[2]=cnt1;
sum2[2]=cnt2;
}
void init2(int a[])
{
cout<<"归并排序前为:\n";
for(int i=0;i<n;i++)
{
temp[i]=a[i];
cout<<a[i]<<" ";
}
cout<<endl;
}
int cnt3,cnt4; //cnt3记录比较次数,cnt4记录赋值次数
void merge_sort(int temp[],int l,int r) //cnt3记录比较次数,cnt4记录赋值次数
{
if(l>=r)return;
int mid=(l+r)>>1;
merge_sort(temp,l,mid); //递归处理数组左半边
merge_sort(temp,mid+1,r); //递归处理数组右半边
int i=l,j=mid+1,k=0;
while(i<=mid && j<=r) //归并,使两个数组有序
{
if(temp[i]<=temp[j])
{
temp2[k++]=temp[i++];
cnt3++,cnt4++;
}
else temp2[k++]=temp[j++],cnt3++,cnt4++;
}
while(i<=mid)temp2[k++]=temp[i++],cnt4++;
while(j<=r)temp2[k++]=temp[j++],cnt4++;
for(int i=l,j=0;i<=r;i++,j++)
{
temp[i]=temp2[j];
}
}
int print_merge_sort()
{
cout<<"归并排序后为:\n";
for(int i=0;i<n;i++)cout<<temp[i]<<" ";
cout<<endl;
cout<<"归并排序比较次数为 "<<cnt3<<" 赋值次数为"<<cnt4<<endl;
sum1[3]=cnt3;
sum2[3]=cnt4;
}
void insert_sort(int a[],int n)
{
cout<<"插入排序前为:\n";
int count1=0,count2=0; //count1记录比较次数,count2记录赋值次数
for(int i=0;i<n;i++) //将随机生成的数组a[n]赋值给temp[n]
{
temp[i]=a[i];
cout<<temp[i]<<" ";
}
cout<<endl;
int i,j;
for(i=1;i<n;i++)
{
int t=temp[i];
for(j=i-1;j>=0 && temp[j]>t;j--) //选择合适位置插入t
{
temp[j+1]=temp[j];
count1++;
}
temp[j+1]=t;
count2++;
}
cout<<"插入排序后为;\n";
for(int i=0;i<n;i++)cout<<temp[i]<<" ";
cout<<endl;
cout<<"插入排序比较次数为 "<<count1<<" 赋值次数为"<<count2<<endl;
sum1[4]=count1;
sum2[4]=count2;
}
int shell_sort1(int a[],int n)
{
cout<<"希尔排序1前为:\n";
int count1=0,count2=0; // count1记录比较次数,count2记录赋值次数
for(int i=0;i<n;i++) //将随即生成的数组a[n]赋值给temp[n]
{
temp[i]=a[i];
cout<<temp[i]<<" ";
}
cout<<endl;
for(int gap=n/2;gap>0;gap=gap/2) //增量的改变
{
for(int i=gap;i<n;i++) //使用插入排序
{
int j=i;
while(j-gap>=0 && temp[j]<temp[j-gap])
{
swap(temp[j],temp[j-gap]);
count2++;
count1++;
j=j-gap;
}
}
}
cout<<"希尔排序后为:\n";
for(int i=0;i<n;i++)cout<<temp[i]<<" ";
cout<<endl;
cout<<"希尔排序1(递增序列为1,2,4....n/2)比较次数为 "<<count1<<" 赋值次数为"<<count2<<endl;
sum1[5]=count1;
sum2[5]=count2;
}
int shell_sort2(int a[],int n)
{
cout<<"希尔排序2为"<<endl;
int count1=0,count2=0; //count1记录比较次数,count2记录赋值次数
for(int i=0;i<n;i++) //将随机生成的数组a[n]赋值给temp[n]
{
temp[i]=a[i];
cout<<temp[i]<<" ";
}
cout<<endl;
int h=1; //h为增量
while (h<=n/3) //最大增量的选择
{
h=h*3+1;
}
cout<<h<<endl;
for (int gap=h; gap>0; gap=(gap-1)/3) //控制增量的变化
{
for (int i=gap;i<n;i++) //使用插入排序
{
for (int j=i;j>gap-1;j-=gap)
{
count1++;
if (temp[j] <temp[j-gap])
{
swap(temp[j],temp[j-gap]);
count2++;
}
else break;
}
}
}
cout<<"希尔排序2后为:\n";
for(int i=0;i<n;i++)cout<<temp[i]<<" ";
cout<<endl;
cout<<"希尔排序2(递增序列为1,4,13....n/3)比较次数为 "<<count1<<" 赋值次数为"<<count2<<endl;
}
int shell_sort3(int a[],int n)
{
cout<<"希尔排序3为"<<endl;
int count1=0,count2=0; //count1记录比较次数,count2记录赋值次数
for(int i=0;i<n;i++) //将随机生成的数组a[n]赋值给temp[n]
{
temp[i]=a[i];
cout<<temp[i]<<" ";
}
cout<<endl;
int h=1; //h为增量
while (h<=n/4) //最大增量的选择
{
h=h*4+1;
}
cout<<h<<endl;
for (int gap=h; gap>0; gap=(gap-1)/4) //控制增量的变化
{
for (int i=gap;i<n;i++)
{
for (int j=i;j>gap-1;j-=gap) //使用插入排序
{
count1++;
if (temp[j] <temp[j-gap])
{
swap(temp[j],temp[j-gap]);
count2++;
}
else break;
}
}
}
cout<<"希尔排序3后为:\n";
for(int i=0;i<n;i++)cout<<temp[i]<<" ";
cout<<endl;
cout<<"希尔排序3(递增序列为1,5,21....n)比较次数为 "<<count1<<" 赋值次数为"<<count2<<endl;
}
int cnt5,cnt6;
void init3(int a[])
{
printf("堆排序前为:\n");
for(int i=0;i<n;i++)
{
temp[i]=a[i];
cout<<a[i]<<" ";
}
cout<<endl;
}
void adjust_heap(int temp[], int father, int n)//判断是不是符合大根堆
{
int left = 2 * father;
int right = 2 * father + 1;
int max = father;
if( left <= n && temp[left] > temp[max])//left<=len,防止节点不存在
max = left,cnt5++;
if( right <= n && temp[right] > temp[max])//a[right]>a[max],判断是不是根节点最大(因为你每个子树都要符合大根堆的性质啊)
max = right,cnt5++;
if(max != father)
{
swap( temp[max], temp[father]);//交换节点
adjust_heap(temp, max, n);
cnt6++;//从当交换后前节点开始, 调整下面的堆
}//这里的 max 是当前 father 的某一个儿子,而不是 father 自身,因为交换后 father本来就是有序的.
}
void heap_sort(int temp[], int n)
{
for(int i = n / 2; i >= 0; --i) //1.创建堆make_heap, 从最后一个非叶子节点开始
adjust_heap(temp, i, n);
for(int i = n-1; i >= 0; --i)//2. 堆排序, 此时 [1, len] 为一个堆
{
swap(temp[0], temp[i]); //将堆顶元素(数组首位) 与堆末元素(数组末位) 互换.
adjust_heap(temp, 0, i-1);
cnt6++; // 此时堆末元素已经有序(存的是最大值),
}// 剩余堆的范围变成了 [1, len-1], 但由于上一步的交换可能破坏堆的性质, 故要进行调整
cout<<"堆排序后为:\n";
for(int i=0;i<n;i++)cout<<temp[i]<<" ";
cout<<endl;
cout<<"堆排序比较次数为 "<<cnt5<<" 赋值次数为"<<cnt6<<endl;
sum1[6]=cnt5;
sum2[6]=cnt6;
index++;
}
int main()
{
int a[1010];
printf("输入数组长度\n");
cin>>n;
for(int i=0;i<n;i++)
{
a[i]=rand();
}
select_sort(a,n); //选择排序
bubble_sort(a,n); // 冒泡排序
init1(a); //快速排序
quick_sort(temp,0,n-1);
print_quick_sort();
init2(a);//归并排序
merge_sort(temp,0,n-1);
print_merge_sort();
insert_sort(a,n);//插入排序
shell_sort1(a,n);//希尔排序1
shell_sort2(a,n);//希尔排序2
shell_sort3(a,n);//希尔排序3
init3(a);
heap_sort(temp,n);
cout<<"比较次数分析"<<endl;
sort(sum1,sum1+7);
for(int i=0;i<7;i++)cout<<sum1[i]<<" ";
cout<<endl;
cout<<"比较次数最多的是"<<"冒泡排序"<<endl;
cout<<"比较次数最少的是"<<"选择排序"<<endl;
cout<<endl;
cout<<"赋值次数分析"<<endl;
sort(sum2,sum2+7);
for(int i=0;i<7;i++)cout<<sum2[i]<<" ";
cout<<endl;
cout<<"赋值次数最多的是"<<"插入排序"<<endl;
cout<<"赋值次数最少的是"<<"选择排序"<<endl;
return 0;
}