数据结构---选择排序(直接选择排序和堆排序图解)

选择排序思想:
每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的 数据元素排完 。

直接选择排序

在元素集合array[i]–array[n-1]中选择关键码最大(小)的数据元素 若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换 在剩余的array[i]–array[n-2](array[i+1]–array[n-1])集合中,重复上述步骤,直到集合剩余1个元素。
在这里插入图片描述直接选择排序的特性总结:

  • 直接选择排序思考非常好理解,但是效率不是太好,实际中少用
  • 时间复杂度
    1. 最好 O(n)
    2. 平均O(n^2)
    3. 最差O(n^2)
  • 空间复杂度:O(1)
  • 稳定性:不稳定
    完整代码:
#include <iostream>
using namespace std;
void Swap(int arr[], int a, int b){
	int temp = arr[a];
	arr[a] = arr[b];
	arr[b] = temp;
}
void selectSort(int array[], int size){
	for (int i = 0; i < size; i++){
		int min = i;
		for (int j = i; j < size; j++){
			if (array[j] < array[min]){
				min = j;
			}
		}
		Swap(array, min, i);
	}
}
void printSort(int array[], int size){
	for (int i = 0; i < size; i++){
		cout << array[i] << " ";
	}
	cout << endl;
}
int main(){
	int arr[] = { 5, 6, 8, 9, 5, 4, 2, 3, 1, 6 };
	int size = sizeof(arr) / sizeof(arr[0]);
	selectSort(arr, size);
	printSort(arr, size);

	system("pause");
	return EXIT_SUCCESS;
}


虽然我们的直接插入排序性能不是太高,但是对于有序的数组来说他的排序的效率是非常的高的,时间复杂度可以是O(N),这种情况只有在数组完全有序的时候才会出现。这和冒泡排序是一样的。但是我们实际的排序并不是按照我们的思想来的,也许我们得到的排序恰好但是我们要排序的逆序,这时候我们就是达到了我们的最差情况。所以这种情况不是太完美,这时候就可以时候我们的堆排序。

堆排序

堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是 通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。
首先我们在二叉树章节了解到了我们的堆是怎么回事,这里我们回顾一下我们的堆,堆也是以这个二叉树,只是二叉树的形式不一样,所有的节点都小于等于他的孩子节点,这叫做小堆,如果所以的节点都大于等于孩子节点,这是的堆就叫做大堆。那么又怎么从我们的堆中去进行排序呢。
我们将一个数组进行建堆,然后每次取出堆顶的元素放在我们的数组的末尾,然后再对我们的首元素进行我们的向下调整,但是最后一个元素不参加调整,知道最后我们就可以得到我们的有序数组了

  1. 先将我们的数组进行建堆(建堆在二叉树章节有介绍,不知道的童鞋可以回去复习复习),达到下面的二叉堆
    在这里插入图片描述
  2. 第一次交换元素,在我们这次交换之后我们的最后一个元素在向下调整的时候就不再参与了,将我们的最小元素浮到我们的首元素上面。
    在这里插入图片描述进行向下调整之后在这里插入图片描述
  3. 第二次交换元素并且进行向下调整之后
    在这里插入图片描述
  4. 第三次交换元素
    在这里插入图片描述
  5. 第四次交换元素
    在这里插入图片描述
  6. 第五次交换元素
    在这里插入图片描述
  7. 第六次交换元素
    在这里插入图片描述
  8. 第七次交换元素
    在这里插入图片描述
  9. 第八次交换元素
    在这里插入图片描述在经过八次交换元素并且向下调整之后我们的序列就变得有序了,因为我们建立的是一小堆,所以我们每次都将最小的放在了我们的数组的最后,这时候我们得到鹅蛋就是我们的降序。
#include <iostream>
using namespace std;
typedef int HPDataType;
void Heapify(int array[], int size, int index) {//向下调整算法
	while (2 * index + 1 < size) {
		int minIdx = 2 * index + 1;
		int rightIdx = 2 * index + 2;
		if (rightIdx < size && array[rightIdx] < array[minIdx]) {
			minIdx = rightIdx;
		}
		if (array[minIdx] >= array[index]) {
			break;
		}

		int t = array[minIdx];
		array[minIdx] = array[index];
		array[index] = t;

		index = minIdx;
	}
}
void CreateHeap(int array[], int size) {
	for (int i = size / 2 - 1; i >= 0; i--) {
		Heapify(array, size, i);
	}
}
int main(){
	//建立小堆,就可以得到降序,建大堆就可以得到我们的升序,只是我们向下调整的时候不一样
	int array[] = { 5, 6, 8, 9, 6, 4, 9, 6, 2, 1, 3 };
	int size = sizeof(array) / sizeof(array[0]);
	CreateHeap(array, sizeof(array) / sizeof(array[0]));
	for (int i = size - 1; i >=0; i--){
		int temp = array[i];
		array[i] = array[0];
		array[0] = temp;
		Heapify(array, i, 0);
	}
	for (int i = 0; i < size; i++){
		cout << array[i] << " ";
	}
	//利用向上调整算法
	system("pause");
	return EXIT_SUCCESS;
}

堆排序特性:

  • 时间复杂度O(NlgN),此时最好最坏和平均情况都是一样的。
  • 空间复杂度O(1)
  • 稳定性:不稳定
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值