选择排序、冒泡排序、快速排序、归并排序

请添加图片描述

1、选择排序

设一个数据集有n个元素,选择这n个元素中最小的一个与第一个元素交换位置,再在剩下的n-1个元素中选择最小的一个与第二个元素交换位置,直到在最后两个元素中选择最小的一个放在倒数第二的位置上,简单选择排序是不稳定排序

f(a,n,i) 当i=n-1时:算法结束
f(a,n,i)否则:通过简单比较挑选a[i…n-1]中最小元素,a[k]放到a[i]处;f(a,n,i+1)

#include<iostream>

using namespace std;


//交换两个元素的值
void swap(int &x,int &y)
{
    
    
	int temp;
	temp=x;
	x=y;
	y=temp;
}
//输出数组a的所有元素
void pt(int a[],int n)
{
    
    
	int i;
	for(i=0;i<n;i++)
		printf("%d ",a[i]);
	printf("\n");
}
//利用递归实现简单排序
void SelectSort(int a[],int n,int i)
{
    
    
	int j,k;
	if(i==n-1) return; //满足递归出口条件
	else{
    
    
		k=i;//记录a[i...n-1]中最小元素的下标
		for(j=i+1;j<n;j++)//在a[i...n-1]找出最小元素a[k]
			if(a[k]>a[j])
				k=j;
		if(k!=i)//最小元素不是a[i]
		swap(a[i],a[k]);
		SelectSort(a,n,i+1);
	}
}
int main()
{
    
    
	int a[]={
    
    3,2,1,4,5,6,9,8,7};
	SelectSort(a,0,9);
	pt(a,9);
}

2、交换排序

2.1、冒泡排序

冒泡排序的基本思想是,对相邻的元素进行两两比较,顺序相反则进行交换。

#include<iostream>

using namespace std;


//交换两个元素的值
void swap(int &x,int &y)
{
    
    
	int temp;
	temp=x;
	x=y;
	y=temp;
}
//输出a的所有元素
void pt(int a[],int n)
{
    
    
	int i;
	for(i=0;i<n;i++)
		printf("%d ",a[i]);
	printf("\n");
}
//利用递归实现冒泡排序
void BubbleSort(int a[],int n,int i)
{
    
    
	int j;
	bool flag;
	if(i==n-1) return;
	else{
    
    
		flag=false;
		for(j=n-1;j>i;j--)
			if(a[j-1]>a[1])
			{
    
    
				swap(a[j],a[j-1]);
				flag=true;
			}
		if(flag==false)
			return;
		else
			BubbleSort(a,n,i+1);

	}
}
int main()
{
    
    
	int a[]={
    
    3,2,1,4,5,6,9,8,7};
	BubbleSort(a,9,0);
	pt(a,9);
}

2.2、快速排序

2.2.1、hoare(左右指针法)

2.2.2、挖坑法(递归)

时间复杂度最好情况nlogn
快速排序实现,从数组中选择一个key,数组中所有比key小的放左边,所有比key大的放右边,第一次递归,n个数被分为2部分,每部分2/n,第logn次递归,n个数被分为n部分,没部分为1,所以时间复杂度为nlogn
空间复杂度最坏情况n平方
如果第一次选择的是数组中的最大或最小值,则还需要递归n-1次,对于n个数来说需要n次递归,所以最坏时间复杂度为n的平方

#include<iostream>

using namespace std;
//输出数组a的值
void pt(int a[],int n)
{
    
    
	int i;
	for(i=0;i<n;i++)
		printf("%d ",a[i]);
	printf("\n");
 } 
 //快速排序算法 
void QuickSort(int a[],int begin,int end)
{
    
    
	if(begin>=end)//如果一次递归开始大于末尾,则结束 
	return; 
	int key=a[begin];//第一个元素为基准 
	int left=begin,right=end;//保留原来初始,结束值 
	while(end>begin)
	{
    
    
		//小的放前面 
		while(a[end]>=key&&end>begin)
		end--;
		a[begin]=a[end];
		//大的放后面 
		while(a[begin]<=key&&end>begin)
		begin++;
		a[end]=a[begin]; 
	}
	a[begin]=key;
	int i=begin;
	QuickSort(a,left,i-1);//基准左侧排序 
	QuickSort(a,i+1,right);//基准右侧排序 
}
//主函数 
int main(){
    
    
	int a[]={
    
    6,5,9,7,11,3,2,5,8};
	QuickSort(a,0,9);
	pt(a,9);
}

3、归并排序

# include<iostream>
using namespace std;
//输出数组 
void pt(int a[],int n)
{
    
    
	int i;
	for(i=0;i<n;i++)
		cout<<a[i]<<" "; 
}
//归并
void Merge(int s[],int temp[],int start,int mid,int end)
{
    
    
	//i为左序列索引,j为右序列索引,k为暂存序列索引 
	int i=start,j=mid+1,k=start;
	//比较左右两个序列元素 
	while(i!=mid+1&&j!=end+1){
    
    
		//右序列元素小,就把右序列元素暂存到temp中 
		if(s[i]>s[j])
		temp[k++]=s[j++];
		//左序列元素小,就把左序列元素暂存到temp中
		else
		temp[k++]=s[i++];
	}
	//左序列有剩余 
	while(i!=mid+1)
		temp[k++]=s[i++];
	//右序列有剩余 
	while(j!=end+1)
		temp[k++]=s[j++];
		//将暂存序列赋值到原来序列中 
	for(int i=start;i<=end;i++)
		s[i]=temp[i];
 } 
 //拆分 
 void MergeSort(int s[],int t[],int start,int end)
{
    
    
	int mid;
	if(start<end)
	{
    
    
		mid=start+(end-start)/2;//避免溢出 
		MergeSort(s,t,start,mid);//左边部分递归划分 
		MergeSort(s,t,mid+1,end);//右边部分递归划分 
		Merge(s,t,start,mid,end);//合并俩个序列 
	}
}
int main()
{
    
    
	int a[9]={
    
    1,5,9,7,5,3,2,5,8};
	int b[9]; 
	MergeSort(a,b,0,8);//注意end=8 
	pt(a,9);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_52108058/article/details/133439238