C语言深入探究选择排序与基数排序使用案例讲解

目录
  • 一.选择排序
    • 1.1 选择排序引入
    • 1.2 选择排序的基本思想与算法分析
    • 1.3 实例说明
    • 1.4 代码实现
    • 1.5 性能分析
  • 二.基数排序
    • 2.1 基数排序基本思想与算法步骤
    • 2.2 实例说明
    • 2.3 代码实现
    • 2.4 性能分析

一.选择排序

1.1 选择排序引入

就像炒股一样,有的人爱炒短线,不断的买进卖出通过差价来盈利,但是频繁的买进卖出,也会因为频繁的手续费和一系列费用获益较少;有的人,不断的进行观察和判断,等到时机一到,果断买进或卖出,这种人交易次数少,而最终收获颇丰;正如我们所说的第一种人就类似排序里的冒泡排序,而第二种人就在排序中可以理解为:在排序时找到合适的关键字再做交换,并且只交换一次完成相应关键字的排序;这就是我们要说的选择排序。

1.2 选择排序的基本思想与算法分析

基本思想:从头至尾扫描序列,找出最小的一个元素,和第一个元素交换,接着从剩下的元素中继续这种选择和交换方式,最终得到一个有序序列

算法分析:

  1. 第1步:在未排序的n个数(a [0] ~a [n- 1])中找到最小数,将它与a [0]交换;
  2. 第2步:在剩下未排序的n- 1个数(a [1] ~a [n- 1])中找到最小数,将它与a[1]交换;
  3. 第n-1步:在剩下未排序的2个数(a [n-2] ~a [n- 1] )中找到最小数,将它与a [n-2]交换;
  4. 得到一个排好序的序列。

1.3 实例说明

以12,32,2,60,42,98为例,排序过程如下:

  • 数字底下有横线的为已排好序的
  • n个值排n-1次即可
  • 每一次都找一个最小值放到前面

1.4 代码实现

代码如下:

void SelectSort(int arr[], int len)
{
	for (int i = 0; i < len - 1; i++)//趟数
	{
		int min_index = i;
		for (int j = i + 1; j < len; j++)//控制找最小值
		{
			if (arr[j] < arr[min_index])
			{
				min_index = j;
			}
		}
		//当内层for循环跑完,此时min_index保存是就是当前待排序序列中最小值的下标
		if (min_index != i)//如果找到的最小值下标  不等于 待排序序列的第一个值的下标  则才有交换的必要性
		{
			int tmp = arr[i];
			arr[i] = arr[min_index];
			arr[min_index] = tmp;
		}
	}
}

1.5 性能分析

  • 时间复杂度:O(n^2)。
  • 空间复杂度:O(1)。
  • 稳定性:不稳定。

尽管与冒泡排序的时间复杂度同为O(n^2),但选择排序的性能还是略优于冒泡排序的。

二.基数排序

2.1 基数排序基本思想与算法步骤

基本思想:将整数按位数切割成不同的数字,然后按每个位数分别比较,最后合并结果。

算法步骤:

  • 将所有待比较数值统一为同样的数位长度,数位较短的数前面补零;
  • 从最低位开始,依次进行一次排序;
  • 从最低位排序一直到最高位排序完成以后, 整合后数列就变成一个有序序列。

2.2 实例说明

以12,32,2,620,42,98,122,289,987,37,56,90为例,排序过程如下:

1.以个位数跑一趟:

个位排序的最终结果:

620,90,12,32,2,42,122,56,987,27,98,289

(这些数据只看个位的话为有序)

2.以十位跑一趟:

十位排序的最终结果:

2,12,620,122,27,32,43,56,987,289,90,98

(这些数据只看十位的话为有序)

3.以百位跑一趟:

百位排序的最终结果:

2,12,27,32,43,56,90,98,122,289,620,987

(数据已完全有序)

2.3 代码实现

代码如下:

//获取数组中最大值的位数
int Get_figure(int* arr, int len)
{
	int max = 0;
	for (int i = 0; i < len; i++)
	{
		if (arr[i] > max)
		{
			max = arr[i];
		}
	}
	int count = 0;
	while (max != 0)
	{
		count++;
		max /= 10;
	}
	return count;
}
//这个函数告诉我传进来的参数n的,对应fin位是多少
//1234,2 -> 2    345,1 ->4    0078,3 -> 0     56789,4 -> 5
int Get_Num(int n, int fin)
{
	for (int i = 0; i < fin; i++)//这里代表需要n 先丢几位最低位
	{
		//n = n/10;
		n /= 10;
	}
	return n % 10;//此时获取剩余属于的最低位即可
}
//一趟桶排序    fin代表这一趟是根据哪个位进行排序(个,十,百......)   0->个位  1->十位...
void Radix(int* arr, int len, int fin)//时间复杂度O(n)
{
	//先将10个桶申请好
	int bucket[10][100] = { 0 };
	int num[10] = { 0 };  //num[1] 代表1号桶中有多少个有效值
	//将所有数据从左向右向对应的桶中存放
	for (int i = 0; i < len; i++)
	{
		int index = Get_Num(arr[i], fin);
		bucket[index][num[index]] = arr[i];
		num[index]++;
	}
	//按照0->9号桶的顺序,依次遵循先进先出的规则将所有值取出来
	int k = 0;
	for (int i = 0; i <= 9; i++)//0->9号桶依次取
	{
		for (int j = 0; j < num[i]; j++)//对应的桶内,从上到下依次取值
		{
			arr[k++] = bucket[i][j];//取出来的值 从前向后放到arr中
		}
	}
}
//基数排序(桶排序)  时间复杂度(d*n)(假设最大值的位数是d) 空间复杂度O(d*n) 稳定性:稳定
void RadixSort(int* arr, int len)
{
	//assert
	//1.首先需要知道 数据中最大值有多少位
	int count = Get_figure(arr, len);

	for (int i = 0; i < count; i++) //D
	{
		Radix(arr, len, i);
	}
}

2.4 性能分析

假设最大值的位数是d

  • 时间复杂度:O (d*n)。
  • 空间复杂度:O (d*n)。
  • 稳定性:稳定。

到此这篇关于C语言深入探究选择排序与基数排序使用案例讲解的文章就介绍到这了,更多相关C语言排序内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • c语言冒泡排序和选择排序的使用代码

    目录 1.冒泡排序 2.选择排序 区别 总结 1.冒泡排序 冒泡排序将一个列表中的两个元素进行比较,并将最小的元素交换到顶部.两个元素中较小的会冒到顶部,而较大的会沉到底部,该过程将被重复执行,直到所有元素都被排序. 冒泡排序示意图 以如图所示的冒泡排序为例,每次比较相邻的两个值,值小的交换到前面,每轮结束后值最大的数交换到了最后.第一轮需要比较4次:第二轮需要比较3次:第三轮需要比较2次:第四轮需要比较1次. 那么如何用二重循环将5个数排序呢?5个数存放在一维数组中,外层循环控制比较多少轮,循

  • C语言排序之 堆排序

    目录 前言: 完全二叉树在数组中下标换算公式 代码工作流程 整体流程 重建堆函数流程 大小顶堆使用场景 时间复杂度 代码 前言: 堆是具有以下性质的完全二叉树 每个节点大于或等于其左右子节点,此时称为大顶(根)堆 ​每个节点小于或等于其左右子节点,此时称为小顶(根)堆 完全二叉树在数组中下标换算公式 假设堆根节点从1开始编号(从1开始方便计算,0下标空着)下面以编号为i的非根节点为例,计算其关联节点的下标公式为:其父节点:i/2其左孩子:2i其右孩子:2i+1 注:把这个完全二叉树按层序遍历放入

  • C语言实现冒泡排序算法的示例详解

    目录 1. 问题描述 2. 问题分析 3. 算法设计 动图演示 4. 程序设计 设计一 设计二 结论 5. 流程框架 6. 代码实现 7. 问题拓展 1. 问题描述 对N个整数(数据由键盘输入)进行升序排列. 2. 问题分析 对于N个数因其类型相同,我们可利用 数组 进行存储. 冒泡排序是在 两个相邻元素之间进行比较交换的过程将一个无序表变成有序表. 冒泡排序的思想:首先,从表头开始往后扫描数组,在扫描过程中逐对比较相邻两个元素的大小. 若相邻两个元素中,前面的元素大于后面的元素,则将它们互换,

  • C语言深入探究冒泡排序与堆排序使用案例讲解

    目录 一.冒泡排序 1.1冒泡排序引入 1.2冒泡排序的核心思想与算法分析 1.3实例说明 1.4优化 1.5代码实现 1.6性能分析 二.堆排序 2.1堆的基础知识 2.1.1堆是什么 2.1.2堆的性质 2.2堆排序的核心思想与基本步骤 2.3实例说明与分析 2.4代码实现 2.5性能分析 一.冒泡排序 1.1冒泡排序引入 对于任何编程语言,当我们学到循环和数组的时候,都会介绍一种排序算法:冒泡排序:深入学习更多排序算法后和在实际使用情况中,冒泡排序的使用还是极少的.它适合数据规模很小的时候

  • C语言数据结构中堆排序的分析总结

    目录 一.本章重点 二.堆 2.1堆的介绍(三点) 2.2向上调整 2.3向下调整 2.4建堆(两种方式) 三.堆排序 一.本章重点 堆 向上调整 向下调整 堆排序 二.堆 2.1堆的介绍(三点) 1.物理结构是数组 2.逻辑结构是完全二叉树 3.大堆:所有的父亲节点都大于等于孩子节点,小堆:所有的父亲节点都小于等于孩子节点. 2.2向上调整 概念:有一个小/大堆,在数组最后插入一个元素,通过向上调整,使得该堆还是小/大堆. 使用条件:数组前n-1个元素构成一个堆. 以大堆为例: 逻辑实现: 将

  • C语言八大排序之堆排序

    目录 前言 一.堆排序的概念 二.堆排序的实现 第一步:构建堆 第二步:排序 三.完整代码 四.证明建堆的时间复杂度 前言 本章我们来讲解八大排序之堆排序.2022,地球Online新赛季开始了!让我们一起努力内卷吧! 一.堆排序的概念 堆排序(Heapsort):利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种.通过堆来进行选择数据,需要注意的是 排升序要建大堆,排降序建小堆. 堆排序使用堆来选数,效率就高了很多. 时间复杂度: 空间复杂度: 稳定性:不稳定 二.堆排序的实

  • C语言数据结构之堆排序详解

    目录 1.堆的概念及结构 2.堆的实现 2.1堆的向下调整算法 2.2堆的向上调整算法 2.3建堆(数组) 2.4堆排序 2.5堆排序的时间复杂度 1.堆的概念及结构 如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树(二叉树具体概念参见——二叉树详解)的顺序存储方式存储在一个一维数组中,并满足:Ki <= K2i+1 且 Ki<= K2i+2 (Ki >= K2i+1 且 Ki >= K2i+2) i = 0,1,2…,则称为小堆(或大

  • C语言对冒泡排序进行升级介绍

    目录 一.补充一下关于void*指针的知识,易于我们对下列函数实现的理解 二.实现排序函数中的核心,比较函数 三.实现排序函数 四.转换函数的实现 总结 简单的冒牌排序只能对一中数组的类型进行排序,现在我们用冒泡排序为基础来改造出一个可以对任意数组排序的排序函数! 后面附有实现的源码! 首先我们以qsort函数为例慢慢分析,然后确定我们的排序函数如何增强,第一步我们从它的参数下手,它一共4个参数. 1.第一个参数类型是void*,qsort函数可以用来对任意类型的数组排序,用void *型指针可

  • C语言冒泡排序算法代码详解

    今天我们来用C语言实现一下冒泡排序 首先我们来了解一下什么叫做冒泡排序,冒泡顾名思义把质量轻的气体(如二氧化碳一样)浮到水面上(如可乐中的二氧化碳),因此冒泡排序的原理就是N个元素在一个周期中,微观上依次进行两两元素的比较,小的元素就被放在前面,大的元素放在后面,以此来进行N-1个周期,来完成冒泡排序. 上文中的一个周期,即外循环,依次进行比较,即内循环. 文字看着很迷糊?没事儿,上图 如图所示,两两元素依次进行比较,小的元素往前移动,大的元素往后移动,直至元素顺序是升序的形式,即移动了 元素-

  • C语言详解冒泡排序实现

    目录 前言 一.冒泡排序是什么 二.具体步骤 1.代码解释 2.读入数据 总结 前言 在排序中,有各种各样的排序方式,今天我们将要来介绍<冒泡排序>.今天会从冒泡排序的具体意义和他的操作来展开. 一.冒泡排序是什么 从左到右,相邻元素进行比较.每次比较一轮,就会找到序列中最大的一个或最小的一个.这个数就会从序列的最右边冒出来. 以从小到大排序为例,第一轮比较后,所有数中最大的那个数就会浮到最右边:第二轮比较后,所有数中第二大的那个数就会浮到倒数第二个位置……就这样一轮一轮地比较,最后实现从小到

随机推荐