【数据结构】比较排序--选择排序

选择排序

  • 直接选择排序
  • 堆排序

直接选择排序

基本思想

  • 在元素集合a[i]–a[n-1]中选择关键码最大(小)的数据元素
  • 若它不是这组元素中国最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个元素)交换
  • 在剩余的a[i]-a[n-2](a[i+1]-a[n-2])集合中,重复上面的步骤,直到集合剩余1个元素

时间复杂度为O(n2),不稳定
代码:

void Swap(int *a, int *b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
}


void Select(int num[], int len)
{
	if (num == NULL || len <= 0)
		return;
	int i = 0;
	//1.确定循环躺数
	for (; i < len - 1; i++)
	{
		int minindex = i;
		int j = i + 1;
		//2.找到无序区的最小值
		for (; j < len; j++)
		{
			if (num[minindex] > num[j])
			{
				minindex = j;
			}
		}
		//与无序区第一个元素交换
		if (minindex != i)
			Swap(&num[minindex], &num[i]);
	}
}

算法优化,一次选两个,一个最大的,一个最小的

void Select_OP(int arr[], int len)
{
	int i = 0;
	int k = 0;//保存无序区第一个元素下标,方便比较
	//一趟确定一个有序区元素,最后一次不用确定,总共len-1次
	for (i = 0; i < len - 1; i++)
	{
		k = i;
		int j = 0;
		//确定无序区最小元素下标
		for (j = i + 1; j < len; j++)
		{
			if (arr[j] < arr[k])
			{
				k = j;
			}
		}
		//如果无序区第一个元素为最小,则没有必要交换
		if (i != k)
		{
			int tmp = arr[k];
			arr[k] = arr[i];
			arr[i] = tmp;
		}
	}
}

堆排序

步骤

  • 创建堆:升序->大堆,降序->小堆
  • 执行如下步骤,直到数组为空
  • 把栈顶元素和当前最堆的最后一个元素交换
  • 堆元素个数减1
  • 再次调整根节点

时间复杂度:O(n*log2n)不稳定

代码:

#include<stdio.h>


void  AdjustDown(int* num, int n, int parent)
{
	if (num == NULL || n <= 0)
		return;
	int child = 2 * parent + 1;
	while (child < n)
	{
		//处理让child指向左右孩子中较大的哪一个
		if ((child + 1 < n) && (num[child] < num[child + 1]))
			child++;
		//比较交换并调整
		if (num[child]>num[parent])
		{
			Swap(&num[child], &num[parent]);
			parent = child;
			child = 2 * parent + 1;
		}
		else
		{
			break;
		}
	}
}
//堆排序
void HeapSort(int* num, int len)
{
	if (num == NULL || len <= 0)
		return;
	//1.建堆(升序->大堆,降序->小堆)
	for (int i = (2 * len - 2) / 2; i >= 0; i--)
	{
		AdjustDown(num, len, i);
	}
	//2.交换最后一个元素和第一个元素
	int end = len - 1;
	while (end > 0)
	{
		Swap(&num[0], &num[end]);
		AdjustDown(num, end, 0);
		--end;
	}
}


猜你喜欢

转载自blog.csdn.net/weixin_41892460/article/details/83045601
今日推荐