各种排序算法

本文通过C++实现插入排序、冒泡排序、选择排序、快速排序、堆排序、归并排序及希尔排序等七种排序算法,并提供了一个交互式的主函数让用户选择不同的排序方法进行测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、工具

C++

2、目的

利用不同的排序算法对一串数字进行排序

4、实现过程

算法1:插入排序

#include <iostream>
#include <stdlib.h>
using namespace std;
//插入排序
void insert_sort(int a[],unsigned int first,unsigned int last){
	int j,i;
	int key;
	for(j=first+1;j<=last;j++){
		key=a[j];
		i=j-1;
		while(i>=first&&key<a[i]){
			a[i+1]=a[i];
			i=i-1;
		}
		a[i+1]=key;
	}
}
//打印
void print(int a[],int count){
	int i;
	for(i=0;i<count;i++)
		cout<<a[i]<<" ";
	cout<<endl;
}
int main(){
	int count;
	cout<<"输入数据集的数目:";
	cin>>count;
	while(count<=0){
		cout<<"数据集数量不正确!"<<endl;
		cout<<"重新输入一遍!"<<endl;
		cin>>count;
	}
	int *a=new int [count];
	cout<<"输入个数为"<<count<<"的数据集:"<<endl;
	int i,num;
	for(i=0;i<count;i++){
		cin>>num;
		a[i]=num;
	}
	cout<<"初始数据集:"<<endl;
	print(a,count);
	insert_sort(a,0,count-1);
	cout<<"选择排序后的数据集:"<<endl;
	print(a,count);
	delete []a;
}

 

算法2:冒泡排序

 

//交换
void swap(int &a,int &b){
	int t=a;
	a=b;
	b=t;
}
//冒泡排序
void bubble_sort(int a[], unsigned int first,unsigned int last){
	int i,j;
	for(i=last-first;i>0;i--){
		for(j=first+1;j<=i;j++){ //不是j<last
		if(a[j]<a[j-1]){ //可以不要{ }
		    //t=a[j]; 这种方法不行结果2,要调用swap???
		    //a[j-1]=a[j];
		    //a[j]=t;
		  swap(a[j],a[j-1]);
		}
		}
	}
}
。。。
//insert_sort(a,0,count-1);
bubble_sort(a,0,count-1);

 

算法3:选择排序

 

void select_sort(int a[], unsigned int first,unsigned int last){
	int i,j,min;
	for(i=0;i<last-first;i++){
		min=i;
		for(j=i+1;j<=last-first;j++){
			if(a[j]<a[min])
				min=j;
		}
		if(min!=i) //min不会指外部min=i那个??
			swap(a[i],a[min]);
	}
}
//insert_sort(a,0,count-1);
//bubble_sort(a,0,count-1);
select_sort(a,0,count-1);

 

算法4:快速排序

 

int part(int a[],int p,int r){
	int i,j,x,t; //以下注释均以第一次执行为例
	x=a[r]; //以最后一个为基准
	i=p-1; //此时i=-1
	for(j=p;j<=r-1;j++){
		if(a[j]<=x){
			i++;//数组下标从0开始,若存在3个数满足小于基准,则最后i=2
			t=a[i];
			a[i]=a[j];
			a[j]=t;//主要是改变下标,使其左边的数小于基准
		}
	}
	t=a[i+1]; //若没有小于基准,直接到这一步
	a[i+1]=a[r];
	a[r]=t;
	return i+1;//这个函数只是返回比基准数小的个数??
}
void quick_sort(int a[],int p,int r){ 
	if(p<r){
		int q;
		q=part(a,p,r);
		quick_sort(a,p,q-1);
		quick_sort(a,q+1,r);
	}
}
//insert_sort(a,0,count-1);
//bubble_sort(a,0,count-1);
//select_sort(a,0,count-1);
quick_sort(a,0,count-1);

算法5:堆排序

inline int parent(int i){return i;}
inline int left(int i){return 2*i+1;}
inline int right(int i){return 2*i+2;}//内联函数,计算节点
//保持堆的性质
void max_heap(int a[],int i,int heapsize){ 
	int l,r,t,largest=0;
	l=left(i);
	r=right(i);
//找到a[i] a[l] a[r] 最大值
	if(l<=heapsize && a[l]>a[i])
		largest=l;
	else
		largest=i;
	if(r<=heapsize && a[r]>a[largest])
		largest=r;
//如果拥有最大值的不是根节点,将a[i] a[largest] 交换 递归调用max_heap对孩子节点处理
	if(largest!=i){
		t=a[i];
		a[i]=a[largest];
		a[largest]=t;
		max_heap(a,largest,heapsize);
	}
}
//构建最大堆
void built_max_heap(int a[],int heapsize){
	int i;
	for(i=heapsize/2;i>=0;--i)
		max_heap(a,i,heapsize);
}
//堆排序
void heap_sort(int a[],int length){
	built_max_heap(a,length);//只需要调用一次,后来的有些相对位置不用变
	int i,t,heapsize=length;
	for(i=heapsize;i>=1;i--){ //对当前堆:将最大的a[0]和末尾a[i]交换		 
		t=a[0];
		a[0]=a[i];
		a[i]=t;
		//①built_max_heap(a,i-1);//也可以,这样就要调用多次,有些步骤多余
		//②heapsize--;
		//max_heap(a,0,heapsize); 这2句可以代替后一句
		max_heap(a,0,i-1);//③建立下一次的最大堆		         
	}
}

算法6:归并排序

void merge(int a[],int p,int q,int r){
	int i,j,k,n1,n2;
	n1=q-p+1;
	n2=r-q;
	int *L=new int[n1+1];
	int *R=new int[n2+1];
	for(i=0;i<n1;i++){
		L[i]=a[p+i];}
	for(j=0;j<n2;j++){
		R[j]=a[q+j+1];}
	L[n1]=INT_MAX;//定义无穷大,也可以1000 10000之类,没有会出错
	R[n2]=INT_MAX;//有些是左2n+1个数与右边2n个数比较
	i=0,j=0;
	for(k=p;k<=r;k++){
		if(L[i]<=R[j]){
			a[k]=L[i];
			i++;}
		else{
			a[k]=R[j];
			j++;
		}
	}
	delete []L;
	delete []R;//可有可无
}
void merge_sort(int a[],int p,int r){
	if(p<r){
		int q;
		q=(p+r)/2;
		merge_sort(a,p,q);//拆分左部分
		merge_sort(a,q+1,r);//拆分右边
		merge(a,p,q,r);//到底每执行上面一次就调用一次还是把左右拆分完才调用?
	}
}

算法7:希尔排序

void shell_sort(int a[],int n){
	int i,j,t,gap=n;
	do{
		gap=gap/3+1;
		for(i=gap;i<n;i++)
			if(a[i]<a[i-gap]){
				t=a[i];
				j=i-gap;
				do{
					a[j+gap]=a[j];
					j=j-gap;
				}while(j>=0 && t<a[j]);
				a[j+gap]=t;
			}
	}
			while(gap>1);
}

	//quick_sort(a,0,count-1);
	shell_sort(a,count);//不同

5、主函数

int main(){  //只适合正负整数,不适合小数
	int count;
	cout<<"输入数据集的数目:";
	cin>>count;
	while(count<=0){
		cout<<"数据集数量不正确!"<<endl;
		cout<<"重新输入一遍!"<<endl;
		cin>>count;
	}
	int *a=new int [count];
	cout<<"输入个数为"<<count<<"的数据集:"<<endl;
	int i,num;
	for(i=0;i<count;i++){
		cin>>num;
		a[i]=num;
	}
	cout<<"初始数据集:"<<endl;
	print(a,count);
	cout<<"……测试3种不同排序方法……"<<endl;
	cout<<"你想用哪一种测试方法?堆排序-1,归并排序-2,快速排序-3 :";
	int c;
	cin>>c;
	cout<<endl;
	switch(c)
		{
		case 1: 
			 heap_sort(a,count-1);
			break;
		case 2:
			 merge_sort(a,0,count-1);
			break;
		case 3:
			 quick_sort(a,0,count-1);
			break;
		default: //若'1''2''3'则错误,那是字符串
			cout<<"输入的数没在定义中!"<<endl;
		}
	cout<<"排序后的数据集:"<<endl;
	print(a,count);
	delete []a;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值