堆排序、归并排序、快速排序

堆排序

#include<bits/stdc++.h>
using namespace std;
//堆排序问题二:如何调整一个堆?
void HeapAdjusting(int a[], int root, int n)
{
	int temp = a[root];
	int child = 2 * root + 1; //左孩子的位置
	while (child < n)
	{
		//找到孩子节点中较小的那个
		if (child + 1 < n && a[child + 1] < a[child])
			child++;
		//如果较大的孩子节点小于父节点,用较小的子节点替换父节点,并重新设置下一个需要调整的父节点和子节点。
		if (a[root] > a[child])
		{
			a[root] = a[child];
			root = child;
			child = 2 * root + 1;
		}
		else
			break;
		//将调整前父节点的值赋给调整后的位置。
		a[root] = temp;
	}
}

//堆排序问题一:如何初始化建堆?
void HeapBuilding(int a[], int n)
{
	//从最后一个有孩子节点的位置开始调整,最后一个有孩子节点的位置为(n-1)/2
	for (int i = (n - 1) / 2; i >= 0; i--)
		HeapAdjusting(a, i, n);
}

//堆排序
void HeapSort(int a[], int n)
{
	//初始化堆
	HeapBuilding(a, n);
	//从最后一个节点开始进行调整
	for (int i = n - 1; i > 0; i--)
	{
		//交换堆顶元素和最后一个元素
		swap(a[0], a[i]);
		//每次交换后都要进行调整
		HeapAdjusting(a, 0, i);
	}
}

归并排序

//merge两个有序数列为一个有序数列
void MergeArr(int a[], int first, int mid, int last, int temp[])
{
	int i = first, j = mid + 1;
	int m = mid, n = last;
	int k = 0;
	//通过比较,归并数列a和b
	while (i <= m && j <= n)
	{
		if (a[i] < a[j])
			temp[k++] = a[i++];
		else
			temp[k++] = a[j++];
	}
	//将数列a或者b剩余的元素直接插入到新数列后边
	while (i <= m)
		temp[k++] = a[i++];
	while (j <= n)
		temp[k++] = a[j++];

	for (i = 0; i < k; i++)
		a[first + i] = temp[i];
}

//归并排序
void MergeSort(int a[], int first, int last, int temp[])
{
	if (first < last)
	{
		int mid = (first + last) / 2;
		MergeSort(a, first, mid, temp);
		MergeSort(a, mid + 1, last, temp);
		MergeArr(a, first, mid, last, temp);
	}
}

快速排序

//快速排序
void QuickSort(int a[], int L, int R)
{
	if (L < R)
	{
		int i = L, j = R, temp = a[i];
		while (i < j)
		{
			//从右向左找小于基准值a[i]的元素
			while (i < j && a[j] >= temp)
				j--;
			if (i < j)
				a[i++] = a[j];
			//从左向右找大于基准值a[i]的元素
			while (i < j && a[i] < temp)
				i++;
			if (i < j)
				a[j--] = a[i];
		}
		//将基准值填入最后的坑中
		a[i] = temp;
		//递归调用,分治法的思想
		QuickSort(a, L, i - 1);
		QuickSort(a, i + 1, R);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值