数据结构课程设计

数据结构的课设,我选择了划水摸鱼,选择了最简单的排序算法性能比较,设计了希尔排序,冒泡排序,选择排序,插入排序,快速排序,希尔排序在老师的要求下,选择了三种增量,进行对比。

#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;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值