数据结构--经典排序之选择排序(超详细!!)

文章目录

选择排序

选择排序(Selection Sort)是一种简单直观的排序算法。它的工作原理是,首先在未排序序列中找到最小(或最大)元素,存放到排序序列的起始位置,然后再从剩余未排序元素中继续寻找最小(或最大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

选择排序的主要优点是与数据规模较小,其在待排序的数据规模较小时,效率较高,且实现简单。但是其缺点是不论数据量大小,都需要进行n*(n-1)/2次比较,时间复杂度为O(n^2),所以不适合数据规模大的情况。

代码实现

方法一 :一次排一个
过程说明

1.初始化外层循环变量i为0,表示当前要排序的元素索引。

2.对于数组中的每个元素(由i指示),执行以下步骤:

2.1.初始化内层循环变量j为i+1,表示从当前元素的下一个元素开始比较。

2.2 遍历剩余的元素(由j指示),找到最小的元素并记录其索引min。

2.3 使用Swap函数交换当前元素(索引为i)和找到的最小元素(索引为min)的位置。

3.外层循环继续,直到所有元素都排好序。

c 复制代码
// 选择排序函数,对数组a中的n个元素进行排序  
void Swap(int* a, int* b) {//用于交换两个整数的值  
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
void SelectSort(int* a, int n) {  
    int i, j, min; // 声明循环变量i, j和最小元素索引min  
  
    // 外层循环,遍历数组的每一个元素  
    for (i = 0; i < n; i++) {  
        // 初始化最小元素的索引为当前索引i  
        min = i;  
  
        // 内层循环,从当前元素的下一个元素开始,遍历剩余的元素  
        for (j = i + 1; j < n; j++) { // 注意,这里从i+1开始,因为前面的元素已经排好序了  
            // 如果找到一个更小的元素,则更新最小元素的索引  
            if (a[j] < a[min]) {  
                min = j;  
            }  
        }  
  
        // 交换当前元素和找到的最小元素的位置  
        Swap(&a[i], &a[min]);  
    }  
}  
  

方法二 :一次排两个
过程说明
1 .Swap 函数是一个简单的值交换函数,它接受两个整数的指针,并交换它们所指向的值。
2 .SelectSort 函数是一个选择排序的变种。在传统的选择排序中,我们通常只找剩余部分的最小值(或最大值)并与首元素交换。但在这里,我们同时找最大值和最小值,并将它们分别与排序区间的两端进行交换。这样做的好处是可以加速排序过程,尤其是在数据部分有序或完全有序的情况下。
3 .在每次循环中,我们首先初始化max和min为区间的起始位置begin。然后,我们遍历begin到end之间的所有元素,找到这个区间内的最大值和最小值的位置。
4 .接着,我们使用Swap函数将begin位置的值与最小值进行交换,这样确保了begin位置始终是已排序的最小值。
5 .如果在交换之前,max恰好是begin,那么由于begin位置的值已经被交换出去,我们需要更新max为min的位置。
6 .然后,我们使用Swap函数将end位置的值与最大值进行交换,这样确保了end位置始终是已排序的最大值。
7.最后,我们缩小排序区间(begin++和end--)

c 复制代码
// 函数Swap用于交换两个整数的值  
void Swap(int* a, int* b) {  
    // 创建一个临时变量tmp,用于存储a指向的值  
    int tmp = *a;  
    // 将b指向的值赋给a指向的变量  
    *a = *b;  
    // 将临时变量tmp的值(即原来a的值)赋给b指向的变量  
    *b = tmp;  
}  
  
// 函数SelectSort实现了选择排序算法,但有所变化,它同时考虑了最大值和最小值  
void SelectSort(int* a, int n) {  
    // begin表示排序区间的起始位置,end表示排序区间的结束位置  
    int begin = 0, end = n - 1;  
      
    // 当begin小于end时,继续进行排序  
    while (begin < end) {  
        // 初始化max和min为begin,它们分别用于记录当前排序区间内的最大值和最小值的位置  
        int max = begin, min = begin;  
          
        // 遍历begin到end之间的所有元素  
        for (int i = begin+1; i <= end; i++) {  
            // 如果找到比当前最大值还大的元素,更新max  
            if (a[i] > a[max]) {  
                max = i;  
            }  
  
            // 如果找到比当前最小值还小的元素,更新min  
            if (a[i] < a[min]) {  
                min = i;  
            }  
        }  
          
        // 将begin位置的值与最小值进行交换  
        Swap(&a[begin], &a[min]);  
          
   // 如果最大值的位置恰好是原来的begin位置(现在已经与最小值交换了),则更新max为min的位置  
        if (max == begin) {  
            max = min;  
        }  
          
        // 将end位置的值与最大值进行交换  
        Swap(&a[end], &a[max]);  
          
        // 缩小排序区间,继续下一轮排序  
        begin++;  
        end--;  
          
    }  
}

使用示例

c 复制代码
#include<stdio.h>

void PrintArray(int* a, int n)//打印
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
}

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


void SelectSort1(int* a, int n) {
	int begin = 0, end = n - 1;
	while (begin < end) {
		int max = begin, min = begin;
		for (int i = begin+1; i <= end; i++) {
			if (a[i] > a[max]) {
				max = i;
			}

			if (a[i] < a[min]) {
				min = i;
			}
		}
		Swap(&a[begin], &a[min]);
		if (max == begin) {
			max = min;
		}
		Swap(&a[end], &a[max]);
		begin++;
		end--;
	}
}

void SelectSort2(int* a, int n) {
	
	for (int i = 0; i < n; i++) {
		int min = i;
		for (int j = i + 1; j < n ; j++) {
			if (a[j] < a[min]) {
				min = j;
			}
		}

		Swap(&a[min], &a[i]);
	}
}

void TestSort()
{
	int a[] = { 6, 3, 9, 1, 5, 8, 2, 4, 7};
	PrintArray(a, sizeof(a) / sizeof(int));//计算数组元素个数并打印

	SelectSort1(a, sizeof(a) / sizeof(int));

	PrintArray(a, sizeof(a) / sizeof(int));
}


int main() {

	TestSort();
	return 0;
}
相关推荐
The_Ticker14 分钟前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
Lenyiin1 小时前
02.06、回文链表
数据结构·leetcode·链表
爪哇学长1 小时前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法
爱摸鱼的孔乙己1 小时前
【数据结构】链表(leetcode)
c语言·数据结构·c++·链表·csdn
Dola_Pan1 小时前
C语言:数组转换指针的时机
c语言·开发语言·算法
繁依Fanyi1 小时前
简易安卓句分器实现
java·服务器·开发语言·算法·eclipse
烦躁的大鼻嘎1 小时前
模拟算法实例讲解:从理论到实践的编程之旅
数据结构·c++·算法·leetcode
C++忠实粉丝2 小时前
计算机网络socket编程(4)_TCP socket API 详解
网络·数据结构·c++·网络协议·tcp/ip·计算机网络·算法
用户37791362947552 小时前
【循环神经网络】只会Python,也能让AI写出周杰伦风格的歌词
人工智能·算法
福大大架构师每日一题2 小时前
文心一言 VS 讯飞星火 VS chatgpt (396)-- 算法导论25.2 1题
算法·文心一言