基于C/C++的交换排序


前言

重新温习数据结构与算法,对一些常用的算法进行代码实现。

一、冒泡排序

1. 代码实现

#include<bits/stdc++.h>
using namespace std;
#define maxSize 100
typedef struct
{
	int Elem[maxSize];	//存储元素 
	int length;			//元素数组长度 
}SqList;

void sortMP(SqList &ql)
{
	int i,j;	//两层循环的标志位 
	bool flag = false;		//改进冒泡排序(减少冒泡次数)的标记位 
	for(i=0;i<ql.length-1&&flag==false;i++)	//冒泡轮次=数组长度-1,且在flag为false的时候进行冒泡 
	{
		flag = true;	//默认进行一个轮次冒泡的时候,将flag置为true 
		for(j=0;j<ql.length-i;j++)	//一个轮次冒泡的具体交换遍历 
		{	
			if(ql.Elem[j]>ql.Elem[j+1])	//如果相邻两个元素是逆序 
			{
				flag = false;		//这个轮次发生了交换,将标记位flag置为false 
				int x;				//两个位置元素进行交换 
				x = ql.Elem[j+1];	
				ql.Elem[j+1] = ql.Elem[j];
				ql.Elem[j] = x;			 
			}
		}
		cout<<i<<": ";				//打印每一轮次冒泡后的结果,便于观察 
		for(int k=0;k<ql.length;k++)
		{
			cout<<ql.Elem[k]<<" ";
		}
		cout<<endl;
	}
} 
int main()
{
	
	SqList QL;
	QL.length = 8;
	for(int i=0;i<QL.length;++i)
	{
		cin>>QL.Elem[i];
	}

	cout<<"插入前元素:";
	for(int i=0;i<QL.length;++i)
	{
		cout<<QL.Elem[i]<<" ";
	}
	cout<<endl;
	
	sortMP(QL);
	
	cout<<endl;
	cout<<"插入后元素:";
	for(int i=0;i<QL.length;++i)
	{
		cout<<QL.Elem[i]<<" ";
	}	
	//cout<<"ok!"<<endl; 
	return 0;
}

2. 运行结果

1.测试排序结果

在这里插入图片描述

2.测试flag的效果

当要排序的数组是升序的时候,仅冒泡一个轮次。
在这里插入图片描述

二、快速排序

1.代码实现

#include<bits/stdc++.h>
using namespace std;
#define maxSize 100
typedef struct
{
	int Elem[maxSize];	//存储元素 
	int length;			//元素数组长度 
}SqList;

int findCenter(SqList &ql,int low,int high)
{
	ql.Elem[0] = ql.Elem[low];	//以第一个元素作为中心点坐标
	
	while(low<high)		//双指针法 
	{
		while(low<high&&ql.Elem[high]>=ql.Elem[0]) high--;	//从数组的最后面开始遍历,找到第一个小于中心点的元素 
		ql.Elem[low] = ql.Elem[high];	//将该元素交换到low的位置,即将小于中心元素数组放在数组的左边 
		
		while(low<high&&ql.Elem[low]<ql.Elem[0]) low++;	//从数组的最前面开始遍历,找到第一个大于中心点的元素 
		ql.Elem[high] = ql.Elem[low];	//将该元素交换到high的位置,即将大于中心元素数组放在数组的右边  
	} 
	//while循环结束时,数组已经划分成为左右两个子数组 
	ql.Elem[low] = ql.Elem[0];//然后把哨兵保存的元素赋值给剩余的中间位置 
	return low;		//同时返回中心坐标,此处返回low和high效果一样。因为上面while循环结束的条件一定是:low=high 
} 
void sortKP(SqList &ql,int low,int high)
{
	if(low<high)	//数组元素长度大于1才有排序的意义 
	{
		int mid = findCenter(ql,low,high);	//快速排序的核心算法,即找中心点位置 
		
		sortKP(ql,low,mid-1);	//递归思想,对小于中心点的子数组进行同样的排序 
			
		sortKP(ql,mid+1,high);	//再对大于中心点的子数组进行同样的排序方法 
	}
}
int main()
{
	
	SqList QL;
	QL.length = 8;
	for(int i=1;i<=QL.length;++i)
	{
		cin>>QL.Elem[i];
	}

	cout<<"插入前元素:";
	for(int i=1;i<=QL.length;++i)
	{
		cout<<QL.Elem[i]<<" ";
	}
	cout<<endl;
	
	sortKP(QL,1,QL.length);
	cout<<endl;
	cout<<"插入后元素:";
	for(int i=1;i<=QL.length;++i)
	{
		cout<<QL.Elem[i]<<" ";
	}	
	//cout<<"ok!"<<endl; 
	return 0;
}

2.运行结果

在这里插入图片描述


总结

  1. 冒泡排序中,为了提高效率不浪费资源,设置flag是为了及时发现排序结果已经完成。
  2. 快速排序以空间换时间,是比较快速的排序方法。但是它最坏的情况其实就是没有改进的冒泡排序。
  3. 快速排序的时候,用数组下标为0的位置作为哨兵,以保存每个子数组的中心坐标元素。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

creator_gzw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值