选择排序和堆排序

 🌈个人主页:羽晨同学 

💫个人格言:“成为自己未来的主人~”  

选择排序

首先,我们先来看一下选择排序的示意图:

我们其实可以很清楚的看到关于选择排序的运行逻辑,我们遍历所有的数组,然后挨个找到大的数字,然后与前面已经排好序的进行交换。 

而这里,其实为了提高效率,我们也可以在遍历的同时找到最大的那一个。

//Sort.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
// 选择排序
void SelectSort(int* a, int n);

首先,我们在头文件中对选择排序进行声明。

接下来,我们对他进行定义:

//Sort.c
#define _CRT_SECURE_NO_WARNINGS
#include"Sort.h"
void Swap(int* px, int* py)
{
	int tmp=*px;
	*px = *py;
	*py = tmp;
}
// 选择排序
void SelectSort(int* a, int n)
{
	int left = 0;
	int right = n - 1;
	while (left < right)
	{
		int mini = a[left];
		int maxi = a[right];
		//一次排序
		for (int i = 0; i < n; i++)
		{
			if (a[i] > maxi)
			{
				Swap(&a[i], &maxi);
			}
			if (a[i] < mini)
			{
				Swap(&a[i], &mini);
			}
		}
		left++;
		right--;
	}
}

大家可以看到这段代码有什么问题吗?

//Test.c
#define _CRT_SECURE_NO_WARNINGS
#include"Sort.h"
int main()
{
	int a[] = { 4,5,8,9,2,1,0,5,8,5 };
	SelectSort(a, sizeof(a) / sizeof(int));
	for (int i = 0; i < sizeof(a) / sizeof(int); i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}

为什么得到的结果会是这样子呢?

我们的本意是想让数组中的值发生交换,但代码却写成了数组中的值和数组外面的值进行交换并且,我们没有对最大值和最小值具体交换的位置进行确切的思考。

所以,我们对代码进行重新编写

//Sort.c
#define _CRT_SECURE_NO_WARNINGS
#include"Sort.h"
void Swap(int* px, int* py)
{
	int tmp=*px;
	*px = *py;
	*py = tmp;
}
// 选择排序
void SelectSort(int* a, int n)
{
	int left = 0;
	int right = n - 1;
	int j = 0;
	while (left < right)
	{
		int mini = left;
		int maxi = right;
		//一次排序
		for (int i = left; i < right; i++)
		{
			if (a[i] > a[maxi])
			{
				Swap(&a[i], &a[maxi]);
			}
			if (a[i] < a[mini])
			{
				Swap(&a[i], &a[mini]);
			}
		}
		j++;
		left++;
		right--;
	}
}

将代码逻辑修改之后,我们发现,结果才正确了。

堆排序

堆排序使用建堆的方式对数组进行排序。

堆排序包括两步,首先,我们需要建堆,其实,我们要利用堆的性质进行排序。

开始的时候,我们先对堆排序进行声明。

//Sort.h
// 堆排序
void AdjustDwon(int* a, int n, int root);
void HeapSort(int* a, int n);

接下来,我们对堆排序进行定义。

//Sort.c

// 堆排序
void AdjustDwon(int* a, int n, int parent)
{
	int child = parent * 2 + 1;
	while (child < n)
	{
		//选出一个大的孩子
		if (child + 1 < n && a[child] < a[child + 1])
		{
			child++;
		}
		if (a[child] > a[parent])
		{
			Swap(&a[child], &a[parent]);
			parent=child;
			child = child * 2 + 1;
		}
		else
		{
			break;
		}
	}
}
void HeapSort(int* a, int n)
{
	//建堆
	for (int i = (n - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDwon(a, n, i);
	}
	//排序
	int end = n - 1;
	while (end > 0)
	{
		Swap(&a[0], &a[end]);
		AdjustDwon(a, end, 0);
		--end;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值