数据结构之排序大综合

冗杂了:

          直接插入排序
          折半插入排序
          希尔排序
          冒泡排序
          快速排序
          选择排序
          堆排序
          归并排序

的一个程序。。。

亲测亲为,可确保 程序的正确性~~~~~~

 

#include<bits/stdc++.h>
#include <windows.h> //注意引用这个头文件
using namespace std;

#define ll long long
#define maxn 10000

ll compare,move;
ll length=maxn;
ll a[maxn+10];
ll dlta[10]={5,3,1};

//直接插入排序
void sort(){
	int i,j;
	for(i=2;i<=length;i++){
		compare++;
		if(a[i]<a[i-1]){
			a[0]=a[i];
			a[i]=a[i-1];
			for(j=i-2;a[0]<a[j];j--){
				a[j+1]=a[j];
				compare++;
				move++;
			}
			a[j+1]=a[0];
		}
	}
} 

//折半插入排序
void Insort(){
	int i,j,m,low,high;
	for(i=2;i<=length;i++){
		a[0]=a[i];
		low=1; high=i-1;
		while(low<=high){
			compare++;
			m=(low+high)/2;
			if(a[0]<a[m]) high=m-1;
			else low=m+1; 
		}
		for(j=i-1;j>=high+1;--j){
			a[j+1]=a[j];
			move++;
		}
		a[high+1]=a[0];
	}
}

//希尔排序
void ShellInsert(int dk){
	int i,j;
	//对顺序表L进行一趟增量为dk的Shell排序,dk为步长因子
	for(i=dk+1;i<=length;++i){//开始将a[i] 插入有序增量子表
		compare++; 
		if(a[i]<a[i-dk]){
			a[0]=a[i];//暂存在a[0]
			for(j=i-dk; j>0 &&(a[0]<a[j]); j=j-dk){
				a[j+dk]=a[j];//关键字较大的记录在子表中后移
				compare++;
				move++;
			}
			a[j+dk]=a[0];//在本趟结束时将a[i]插入到正确位置
		}
	}
}



void ShellSort(){
	int k;
//按增量序列dlta[0…t-1]对顺序表L作Shell排序
	for(k=0;k<3;++k)
    	ShellInsert(dlta[k]);//增量为dlta[k]的一趟插入排序  
}

//冒泡排序
void MPsort(){
	int i,j,t;
	for(j=1;j<=length-1;j++){
		for(i=0;i<=length-j-1;i++){
			compare++;
			if(a[i]>a[i+1]){
				t=a[i];
				a[i]=a[i+1];
				a[i+1]=t;
				move++;
			}
		}
	}
}

//快速排序
int Partition(int low,int high)
{
	a[0]=a[low];
	int key=a[low];
	while(low < high)
	{
		compare++;
		while(low<high&&a[high]>=key){
			--high;
			compare++;
		}
	    a[low] = a[high];
	    move++;
		while(low<high&&a[low]<=key){
			++low;
			compare++;
		}
		a[high] = a[low];
		move++;
	}
	a[low]=a[0]; 
	return low;
}

void QSort(int low,int high) 
{
	int mid;
	compare++;
	if(low<high)
	{
		mid=Partition(low,high);
        QSort(low,mid-1); 
        QSort(mid+1,high); 
    }
} 

//简单选择排序
void SelectSort()
{
	int i,j,t; 
	for(i=1;i<length;++i)
	{ //在a[i..L.length] 中选择最小的记录
		int k=i;
	    for(j=i+1;j<=length;j++){
	    	compare++;
	    	if(a[j]<a[k]) k=j;
		}
	    if(k!=i){
	    	t=a[i];
			a[i]=a[k];
			a[k]=t;
			move++;
		}            
	}
} 

//堆排序
void HeapAdjust(int s,int m){
	int i,j,rc;
	rc=a[s];
    //沿key较大的孩子结点向下筛选
    for(j=2*s;j<=m;j*=2)
    {
    	compare++;
        if(j<m&&a[j]<a[j+1]) ++j;
        compare++;
        if(rc>=a[j]) break;
        a[s]=a[j];
        s=j;
        move++;
    }
    a[s]=rc;
} 

void CreatHeap()
{
    int n,i;
    n=length;
    //反复调用HeapAdjust()函数
    for(i=n/2;i>0;--i)
        HeapAdjust(i,n);
}

void HeapSort()
{
    int i,x;
    CreatHeap();
    for(i=length;i>1;--i)
    {
        x=a[1];
        a[1]=a[i];
        a[i]=x;
        move++;
        HeapAdjust(1,i-1);
    }
} 

//归并排序
void Merge(ll S[],ll T[],ll low,ll mid,ll high)
{
	ll i,j,k;
	i=low,j=mid+1,k=low;
	while(i<=mid&&j<=high){
		compare++;
		if(S[i]<=S[j]) T[k++]=S[i++];
		else T[k++]=S[j++];
	}
	while(i<=mid){
		T[k++]=S[i++];
		move++;
	}
	while(j<=high){
		T[k++]=S[j++];
		move++;
	}
}

void Msort(ll S[],ll T[],ll low,ll high){
	ll R[maxn+10];
	compare++;
	if(low==high){
		T[low]=S[low];
		move++;
	}
	else{
		ll mid=(low+high)/2;
		Msort(S,R,low,mid);
		Msort(S,R,mid+1,high);
		Merge(R,T,low,mid,high);
	}
} 

int main(){
	//定义两个结构体,来记录开始和结束时间
	DWORD start, stop;
    int i;
    while(true){
    	for(i=1;i<=length;i++){//随机生成maxn个数:
			a[i]=rand();
		}
		int t;
		move=0,compare=0;
		puts("——————请选择排序方式——————");
		puts("1 直接插入排序");
		puts("2 折半插入排序");
		puts("3 希尔排序");
		puts("4 冒泡排序");
		puts("5 快速排序");
		puts("6 选择排序");
		puts("7 堆排序");
		puts("8 归并排序");
		scanf("%d",&t);
		switch(t){
			case 1 :{
				//开始记时
				start = GetTickCount();
				sort();
				//结束记时
				stop = GetTickCount();
				break;
			}
			case 2 :{
				//开始记时
				start = GetTickCount();
				Insort();
				//结束记时
				stop = GetTickCount();
				break;
			}
			case 3 :{
				//开始记时
				start = GetTickCount();
				ShellSort(); 
				//结束记时
				stop = GetTickCount();
				break;
			}
			case 4:{
				//开始记时
				start = GetTickCount();
				MPsort(); 
				//结束记时
				stop = GetTickCount();
				break;
			}
			case 5:{
				//开始记时
				start = GetTickCount();
				QSort(1,length); 
				//结束记时
				stop = GetTickCount();
				break;
			}
			case 6:{
				//开始记时
				start = GetTickCount();
				SelectSort();
				//结束记时
				stop = GetTickCount();
				break;
			}
			case 7:{
				//开始记时
				start = GetTickCount();
				HeapSort();
				//结束记时
				stop = GetTickCount();
				break;
			}
			case 8:{
				//开始记时
				start = GetTickCount();
				Msort(a,a,1,length);
				//结束记时
				stop = GetTickCount();
				break;
			}
		}
		for(i=1;i<=length;i++){//输出排序完成的maxn个数:
			printf("%d ",a[i]);
		}
		printf("\n");
		//计算时间差,并打印
		printf("time: %lld ms\n", stop - start);
		printf("比较次数:%lld\n",compare);
		printf("移动次数:%lld\n",move);
	}
	return 0;
}

 

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值