十大排序之选择排序

本文详细介绍了选择排序的基本原理、动图演示、代码实现,并探讨了其在已排序数组上的性能。通过增加一个判断标志,实现了在数组已排序情况下的优化,减少了不必要的比较次数。同时,给出了原版与优化版的性能对比,展示了改进方案的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

选择排序

选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。

唯一的好处可能就是不占用额外的内存空间了吧。

1. 算法步骤

  • 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。

  • 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

  • 重复第二步,直到所有元素均排序完毕。

2. 动图演示

img

3.代码实现

void swap(int* a, int* b)//该函数的作用是进行交换,针对int类型的变量
{
	int temp;
	temp = *a;
	*a = *b;
	*b = temp;
}
void selection_sort(int arr[], int len)//默认是对int类型的数组进行数据交换
{
	int pos = 0;//指示数组中当前遍历中最小元素
	for (int i = 0; i < len - 1; i++)
	{
		pos = i;
		for (int j = i + 1; j < len; j++)
		{
			if (arr[pos] > arr[j])
			{
				pos = j;//标记这次迭代中数据元素最小的位置
			}
		}
		swap(arr + i, arr + pos);
	}
}
void main()
{
	int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };//定义一个待排序的数组
	int len = sizeof(arr) / sizeof(*arr);//获取数组的大小
	printf("\nsort before\n");
	for (int i = 0; i < len; i++)//打印排序前数组元素
	{
		printf("%d\t",arr[i]);
	}
	selection_sort(arr, len);//对数组进行排序,数组长度为len
	printf("\nsort after\n");
	for (int i = 0; i < len; i++)//打印排序后数组元素
	{
		printf("%d\t",arr[i]);
	}
	system("pause");
}

4.改进版本

4.1.疑问

不妨试想一下,对一个升序的数组进行排序操作,所需要的次数是多少?

为了测试次数,更改之后的代码为:(创建一个变量来记录循环处理的次数

void selection_sort(int arr[], int len)//默认是对int类型的数组进行数据交换
{
	int pos = 0;//指示数组中当前遍历中最小元素
	for (int i = 0; i < len - 1; i++)
	{
		pos = i;
		for (int j = i + 1; j < len; j++)
		{
			count++;//用于计算运行的总次数,只是为了测试,不加这个语句也是可以的
			if (arr[pos] > arr[j])
			{
				pos = j;//标记这次迭代中数据元素最小的位置
			}
		}
		swap(arr + i, arr + pos);
	}
}

结果如下:

一个已经排序完成的数组再次进行排序却还要进行55次。难道不觉得这个算法有问题吗?

4.2.解析

无论待排序的数组中数据元素的顺序如何,排序的总次数是不会改变的。总次数与数组的大小如下。
sum=len∗(len−1)/2 sum = len*(len-1)/2 sum=len(len1)/2

sum : 排序的总次数 len:数组长度 😄

4.3.解决方案

void selection_sort_advance(int arr[], int len)//默认是对int类型的数组进行数据交换
{
	int pos = 0;//指示数组中当前遍历中最小元素
	int flag = false;
	for (int i = 0; i < len-1; i++)
	{
		pos = i;
		flag = false;
		for (int j = i+1; j < len; j++)
		{
			count++;
			if (arr[pos] > arr[j])
			{
				pos = j;
				flag = true;
			}
		}
		if (flag == false)
		{
			return;
		}
		swap(arr + i, arr + pos);
	}
}

结果如下:

4.4.性能对比

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
void swap(int* a, int* b)
{
	int temp;
	temp = *a;
	*a = *b;
	*b = temp;
}
int count = 0;
void selection_sort_advance(int arr[], int len)//默认是对int类型的数组进行数据交换
{
	int pos = 0;//指示数组中当前遍历中最小元素
	int flag = false;
	for (int i = 0; i < len-1; i++)
	{
		pos = i;
		flag = false;
		for (int j = i+1; j < len; j++)
		{
			count++;
			if (arr[pos] > arr[j])
			{
				pos = j;
				flag = true;
			}
		}
		if (flag == false)
		{
			return;
		}
		swap(arr + i, arr + pos);
	}
}
void selection_sort(int arr[], int len)//默认是对int类型的数组进行数据交换
{
	int pos = 0;//指示数组中当前遍历中最小元素
	for (int i = 0; i < len - 1; i++)
	{
		pos = i;
		for (int j = i + 1; j < len; j++)
		{
			count++;
			if (arr[pos] > arr[j])
			{
				pos = j;
			}
		}
		swap(arr + i, arr + pos);
	}
}
void main()
{
	int arr[] = { 5,3,4,1,2,0,6,7,8,9,10,11,12 };//定义一个待排序的数组
	int arr1[] = { 5,3,4,1,2,0,6,7,8,9,10,11,12 };//定义一个待排序的数组
	int len = sizeof(arr) / sizeof(*arr);
	printf("\nsort before\n");
	for (int i = 0; i < len; i++)
	{
		printf("%d\t", arr[i]);
	}
	selection_sort(arr,len);
	printf("\nselection_sort after\n");
	for (int i = 0; i < len; i++)
	{
		printf("%d\t", arr[i]);
	}
	printf("\nselection_sort:%d\n", count);
	count = 0;//清除selection_sort函数处理的次数
	selection_sort_advance(arr1, len);
	printf("\nselection_sort_advance after\n");
	for (int i = 0; i < len; i++)
	{
		printf("%d\t", arr1[i]);
	}
	printf("\nselection_sort_advance:%d\n", count);
	system("pause");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值