【C++】 --几种简单排序和堆排序详解

本篇博客只介绍冒泡排序,插入排序,选择排序,以及堆排序详解

冒泡排序、插入排序、选择排序

因为这几种排序都相对比较简单,其他的博主都写得很完善,我就只给上我的代码,连同后面的堆排序给出测试结果截图:

void Bubblesort(int *a, int n)   //冒泡排序
{
	for (int i = 0; i < n - 1; i++)
	{
		for (int j = 0; j < n - i - 1; j++)
		{
			if (a[j] > a[j + 1])
			{
				int temp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = temp;
			}
		}
	}
}

void Selectsort(int *a, int n)  //选择排序  不断选出每一躺中最小的元素
{
	int temp = 0;
	for (int i = 0; i < n; i++)
	{
		temp = i;
		for (int j = i + 1; j < n; j++)
		{
			if (a[j] < a[temp])
			{
				temp = j;
			}
		}
		int ret = a[i];
		a[i] = a[temp];
		a[temp] = ret;
	}
}

void insertSort(int *a, int begin, int end)
{
	for (int i = 1; i < end; i++)
	{
		int temp = a[i];
		int j = i - 1;
		for (; j >= 0; j--)
		{
			if (temp < a[j])
			{
				a[j + 1] = a[j];
			}
			else
				break;
		}
		a[j + 1] = temp;
	}
}

堆的定义

每个节点的值都大于或者等于其左右孩子节点的值,称为大顶堆;或者每个节点的值都小于或者等于其左右孩子节点的值,称为小顶堆。

  • 升序采用大顶堆,降序采用小顶堆

堆排序的基本思想

如果要升序,则将待排序的序列构成一个大顶堆,(反之就是一个小顶堆)此时,整个序列的最大值就是对顶的根结点,将它与堆数组的末尾元素进行交换,此时末尾元素就是最大值,然后将剩下的n-1个数字再重新构造一个堆,这样就得带n个元素中的次小值。如此反复执行,便可以得到一个有序序列。

如图所示:假设要对4,6,8,5,9进行排序
在这里插入图片描述

  • 第一步,我们从第一个非叶子节点开始,也就是6这个节点,从左到右,从下岛、到上进行调整。
    在这里插入图片描述
  • 再找第二个非叶子节点,也就是4,由于[4,9,8]中,9最大,因此4和9进行交换
    在这里插入图片描述
  • 第三步,交换后导致[4,5,6]结构混乱,继续调整,[4,5,6]中6最大,交换,4和6
    在这里插入图片描述
    此时我们就将一个无序序列构建成了一个大顶堆。
    接下来就是第二个大的步骤,将堆顶元素9和末尾元素4进行交换,然后根据上述办法对剩下的n-1个元素进行调堆,如此反复进行交换,重建。
    在这里插入图片描述
    继续调堆,因为倒数第一个非叶子节点6比它的孩子大,不用调堆,再继续倒数第二个非叶子节点4比它的右孩子8小,因此再次进行交换
    在这里插入图片描述
    堆顶元素8和末尾元素5进行交换,得到第二大元素8
    在这里插入图片描述以此种方法反复进行,最终得到的序列为:
    在这里插入图片描述
    堆排序的代码:
void HeapAjustUp(int* a,int i,int n)  //升序需要向上调堆,最后得出的堆是大顶堆
{  //n表示的是堆的大小,i表示开始从i这个位置开始调堆
	int parent = i;
	int child = 2 * i + 1;

	while (child < n)
	{
		if (a[child] < a[child + 1] && child + 1 < n)
			child++;

		if (a[parent] < a[child])
		{
			swap(&a[parent], &a[child]);
			parent = child;
		}
		child = child * 2 + 1;
	}
}

void BuidHeap(int *a,int heapsize)
{
	for (int i = heapsize / 2 - 1; i >= 0; i--)
	{
		HeapAjustUp(a, i, heapsize);
	}
}
void HeapSort(int *a, int heapsize)
{
	BuidHeap(a, heapsize);
	for (int i = heapsize-1; i > 0; i--)
	{
		swap(&a[0], &a[i]);   //将第一个和最后一个元素交换
		HeapAjustUp(a,0,i);
	}

}

这几种排序的结果截图:
在这里插入图片描述
建堆的时间复杂度:O(n)
调整堆:n(logn)(因为每一次都是从根结点往下循环查找,所以每一次时间都是logn,总时间:logn(n-1)=nlogn-logn);
最优的情况:所有叶子铺满最底层
最差的情况:所有叶子铺满半层的时候

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值