几种排序算法代码详解

本文详细介绍了C++实现的快速排序算法,并将其与选择排序、插入排序和希尔排序进行了对比。通过实例展示了如何使用这些算法对整数数组进行排序,同时讨论了各自的效率和适用场景。

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

#include <windows.h>
#include<iostream>
#include <time.h>
using namespace std;


//分割数组为两部分,一部分大于temp,一部分小于temp
int partion(int* arr, int begin, int end)
{
	int i = begin;//记录开头
	int j = end;//记录结尾
	int temp = arr[begin];//记录某个值,用来分割数组,一般取数组开头的值

	while (i < j)//循环条件为前段下标大于后段下标,数组还未遍历完
	{
		while (arr[j] >= temp && i < j)//一直循环,直到找到小于temp的数
			j--;//循环时j前移
		arr[i] = arr[j];//找到了小于temp的数,将它赋值给前面的arr[i]
		while (arr[i] < temp && i < j)//一直循环,直到找到大于temp的数
			i++;//循环时i后移
		arr[j] = arr[i];//找到了大于temp的数,将它赋值给前面的arr[j]
	}//循环结束
	arr[i] = temp;//此时i=j,把temp存入
	return i;//此时的i即为分界点,一部分大于temp,一部分小于temp
}

//快速排序算法(从小到大)
//arr:需要排序的数组,begin:需要排序的区间左边界,end:需要排序的区间的右边界
void quickSort(int* arr, int begin, int end)
{
	if (begin >= end)//递归终止条件
		return;
	int mid = partion(arr, begin, end);//记录分割点下标
	quickSort(arr, begin, mid - 1);//递归前半部分
	quickSort(arr, mid + 1, end);//递归后半部分
}

//选择排序:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,
//然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾
void selectSort(int *arr,int n)
{
	int minIndex = 0;//初始化最小值索引为0
	int min = 0;//初始化最小值为0
	for (int i = 0; i < n; i++)//遍历元素
	{
		minIndex = i;//暂存索引
		min = arr[minIndex];//暂存值
		for (int j = i + 1; j < n; j++)//从i+1向后遍历
		{
			if (arr[j] < min)//如果小于暂存值
			{
				minIndex = j;//更新最小值索引
				min = arr[minIndex];//更新最小值
			}
		}
		if (minIndex != i)//如果找到比arr[i]小的值
		{//交换两者的值
			arr[minIndex] = arr[i];
			arr[i] = min;
		}
	}
}

//插入排序:每次将一个待排序的元素与已排序的元素进行逐一比较,直到找到合适的位置按大小插入
//开始时,有序序列只有一个元素就即第一个元素
void insertSort(int *arr,int n)
{
	for (int i = 0; i < n; i++)
	{
		int insertVal = arr[i];//暂存待插入值
		int index = i - 1;//为什么不是int index = i?因为insertVal要跟它的前一个数比较
						  //如果非要写int index = i也可以,但是要修改后面的代码逻辑
		while (index >= 0 && arr[index] > insertVal)
		{//当遍历到的值比待插入值大时
			arr[index + 1] = arr[index];//该值往后移
			index--;//往前遍历
		}//遍历到比待插入值小的元素
		arr[index + 1] = insertVal;//在该元素(比待插入值小的元素)后方插入insertVal
	}
}

// 生成有n个元素的随机数组,每个元素的随机范围为[rangeL, rangeR] 闭区间
int* generateRandomArray(int n, int rangeL, int rangeR) {
	//assert(rangeL <= rangeR);

	int* arr = new int[n]; // 创建一个 n个元素的数组

	srand(time(NULL)); // 随机种子
	for (int i = 0; i < n; i++)
		arr[i] = rand() % (rangeR - rangeL + 1) + rangeL;
	return arr;
}

//归并排序part2
void merge(int* arr, int left, int mid, int right)
{
	int* temp = new int[right - left + 1];//新建暂存数组
	int i = left;//记录左数组开始下标
	int j = mid + 1;//记录右数组开始下标
	int k = 0;//记录暂存数组索引值
	while (i <= mid && j <= right)//当两个数组都没遍历完
	{
		if (arr[i] < arr[j])//取较小值存入temp
			temp[k++] = arr[i++];
		else
			temp[k++] = arr[j++];
	}
	while (i <= mid)//如果还剩左数组没遍历完
		temp[k++] = arr[i++];//直接放入temp
	while (j <= right)//如果还剩右数组没遍历完
		temp[k++] = arr[j++];//直接放入temp
	k = 0;
	//将temp中的元素全部拷贝到原数组中
	while (left <= right) 
	{
		arr[left++] = temp[k++];
	}
	delete[] temp;//删除暂存数组temp
}

//归并排序:利用归并思想将两个的有序数列合并成一个有序数列
void mergeSort(int* arr, int left, int right)
{
	if (left >= right)//没有等号会栈溢出
		return;
	int mid = left + ((right - left) >> 1);//记录数组中间值
	mergeSort(arr, left, mid);//递归左子数组
	mergeSort(arr, mid + 1, right);//递归右子数组
	merge(arr, left, mid, right);//按顺序合并数组

}
//希尔排序:直接插入排序算法的一种更高效的改进版本
void shellSort(int* arr, int n)
{
	for (int gap = n / 2; gap > 0; gap /= 2)
	{//初始化间隔为数组长度一半,步长为当前间隔的一半
		for (int i = gap; i < n; i++)
		{//初始化i为某一组元素的第二个
			int temp = arr[i];//记录当前元素
			int j = i - gap;//记录某一组元素的第一个
			while (j >= 0 && arr[j] > temp)//当同组前面的值比后面值大时
				{
					arr[j + gap] = arr[j];//同组元素后移
					j -= gap;//j往前遍历
				}//遍历完成
			arr[j + gap] = temp;//将暂存值放入arr[j + gap]
			//注意不是arr[j],因为是当前元素跟前一个元素比,
			//当前一个元素(arr[j])不满足要求时,将当前值放入arr[j]同组元素的后面
			/*for (j = i - gap; j >= 0 && arr[j] > temp; j -= gap)
				arr[j + gap] = arr[j];
			arr[j + gap] = temp;*/
		}
	}
}

int main()
{
	SetConsoleOutputCP(CP_UTF8);//防止中文乱码
	clock_t start, finish;
	//int n = 8000000;
	//int *num= generateRandomArray(n,0,999);
	int n = 8;
	int num[] = { 0, 1, 2, 4, 2, 2, 3, 1, 4 };
	start = clock();//记录开始时间
	
	//selectSort(num,n);
	quickSort(num, 0, n - 1);
	//mergeSort(num, 0, n - 1);
	//insertSort(num,n);
	//shellSort(num, n);
	finish = clock();//记录结束时间
	cout << "time:" << (double)(finish - start) / CLOCKS_PER_SEC << endl;
	cout << "排序后的数组为:" << endl;
	for (int i = 0; i < n; i++)
		cout << num[i] << ' ';
	cout << endl;
	//delete[] num;
	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值