【C语言】简单排序:冒泡排序和选择排序(含图解)

news2025/1/12 6:21:16

文章目录

  • 1. 冒泡排序
    • 1.1 思想
    • 1.2 代码实现
  • 2. 选择排序
    • 2.1 思想
    • 2.2 代码实现

1. 冒泡排序

1.1 思想

选择排序算法思想:以升序为例

  • 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  • 针对所有的元素重复以上的步骤,除了最后一个。
  • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

以10个元素为例(升序):10个数一共要交换9轮,每一轮归位一个数,9轮后排序完成。

  1. 第一轮有10个元素,对这10个元素中的相邻元素进行两两比较,共比较9次,如果前面的元素大于后面的元素,则进行交换,第一轮结束后,最大的元素放在了最后一个位置;
  2. 第二轮对剩余的9个元素中的相邻元素进行两两比较,如果前面的元素大于后面的元素,则进行交换,第二轮结束后,这9个元素中最大的元素被放在了倒数第二个位置;
  3. …;
  4. 第九轮对剩余的2个元素中的相邻元素进行两两比较,如果前面的元素大于后面的元素,则进行交换,第九轮结束后,这2个元素中最大的元素被放在了正数第二个位置,此时最小的元素也放到了第一个位置,排序结束。

假设待排序序列为 [5,1,4,2,8],其冒泡排序图解如下:

第一轮排序图解:
在这里插入图片描述

第二轮排序图解:
在这里插入图片描述

第三轮排序图解:
在这里插入图片描述

第四轮排序图解:
在这里插入图片描述

1.2 代码实现

#include <stdio.h>
#define N 10
int main()
{
	int i, j, t;
	int a[N] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
	
	// 冒泡排序(升序)
	for(i = 1; i < N; i++) // 10个数要交换9轮
		for(j = 0; j < N - i; j++) // 第一轮比较9次,第二轮比较8次...第9轮比较一次
			if(a[j] > a[j+1]) // 如果前面的数比后面的数大,则交换
			{
				t = a[j];
				a[j] = a[j+1];
				a[j+1] = t;
			}
			
	// 打印排序后的数组			
	for(i = 0; i < 10; i++)
		printf("%d ", a[i]);
	printf("\n");
	return 0;
}

注:外层循环i控制交换几轮,内层循环j控制每轮对数字比较几次,因此ij 的边界值需要注意。
1.此处N为10,i=1i<Ni的取值为1-9,共交换9轮,说明i的取值没有问题
2. j=0j<N-i
i=1时,j的取值为0-8,由于要比较 a[j]>a[j+1],也就是可以比较到a[8]>a[9],第一轮对所有数进行了比较(比较9次),说明j的取值没有问题
i=2时,j的取值为0-7,由于要比较 a[j]>a[j+1],也就是可以比较到a[7]>a[8],第二轮对剩余的9个数进行了比较(比较8次)

i=9时,j的取值为0,由于要比较 a[j]>a[j+1],也就是可以比较到a[0]>a[1],第九轮对剩余的2个数进行了比较(比较1次)

运行结果如下:

在这里插入图片描述

注:如果想让数组中的数据降序排序,则只需要将上述代码中的 a[j] > a[j+1] 改为 a[j] < a[j+1]即可。

在这里插入图片描述

将冒泡排序封装成函数,代码如下:

#include <stdio.h>

void bubbleSort(int arr[], int len);
void swap(int *a, int *b);
void printArray(int arr[], int len);

// 冒泡排序(升序)
void bubbleSort(int arr[], int len) {
	int i, j;
	for(i = 1; i < len; i++) { // 外层循环,控制排序的趟数
		for(j = 0; j < len - i; j++) { // 内层循环,控制比较的次数
			if(arr[j] > arr[j+1]) { // 比较相邻的元素的大小
				swap(&arr[j], &arr[j+1]);
			}
		} 
	} 		
}

// 两数交换
void swap(int *a, int *b) {
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

// 打印数组
void printArray(int arr[], int len) {
	int i;
	for(i = 0; i < 10; i++) {
		printf("%d ", arr[i]);
	}	
	printf("\n");
}

int main() {
	int a[] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
	int len = sizeof(a) / sizeof(int); // 数组长度
	printf("排序前:");
	printArray(a, len);
	bubbleSort(a, len);
	printf("排序后:");
	printArray(a, len);
	return 0;
}

运行结果:

在这里插入图片描述

注:通过传递数组名参数到子函数中,再获得数组长度是不可行的,这样计算出的长度恒为1;只能在数组定义所在的代码区中获取数组长度,再将获取后的数组长度作为实参传给函数。因此函数的的形参两个(数组和数组长度)bubbleSort(int arr[], int len),而不能只传入数组 bubbleSort(int arr[])

#include <stdio.h>

void bubbleSort(int arr[]) {
	int len = sizeof(arr)/sizeof(int);
	printf("%d\n", len); // 1
		
}

int main() {
	int a[] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
	int len = sizeof(a) / sizeof(int);
	printf("%d\n", len); // 10
	bubbleSort(a);
	return 0;
}

2. 选择排序

2.1 思想

选择排序算法思想:以升序为例

  • 首先在未排序序列中找到最小元素,存放到排序序列的起始位置。
  • 再从剩余未排序元素中继续寻找最小元素,然后放到已排序序列的末尾。
  • 重复第二步,直到所有元素均排序完毕。

以10个元素为例(升序):10个数一共要交换9轮,每一轮归位一个数,9轮后排序完成。

  1. 第一轮在10个元素找出最小的元素,放在第一个位置;
  2. 第二轮在剩余9个元素中找出最小的元素,放在第二个位置;
  3. …;
  4. 第9轮在剩余2个元素中找出最小的元素,放在第9个位置,此时最后一个元素也放到了最后一个位置,排序结束。

选择排序图解:

在这里插入图片描述

2.2 代码实现

代码实现思路:

  • 有N个数,N个数需要交换N-1轮,且数组下标从0开始,那么最外层循环是i的取值是[0,N-1)
  • 定义k变量,表示当前最小数的下标,每轮循环时,默认假设初始值是最小值,即初始赋值k=i
  • 遍历除当前最小数以外剩余的数,如果发现有比当前最小数更小的数,则记录更小的数的下标,然后两数交换
#include <stdio.h>
#define N 10
int main()
{
	int i, j, k, t;
	int a[N] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};

	// 选择排序(升序)
	for(i = 0; i < N - 1; i++) // 10个数要交换9轮
	{
		k = i; // 记录最小数下标,初始值为i(假设当前数就是最小数)
		for(j = i + 1; j < N; j++) // 遍历剩余的数,看有没有比当前最小数更小的数
			if(a[j] < a[k]) // 如果存在比当前数更小的数
				k = j; // 更改最小数的下标值
		// 如果最小数的下标值有更改,则交换两数
		if(k != i) 
		{
			t = a[i];
			a[i] = a[k];
			a[k] = t;
		}
	}
	
	// 打印排序后的数组
	for(i = 0;i < 10; i++)
		printf("%d ", a[i]);
	printf("\n");
	return 0;
}

注:如果想让数组中的数据降序排序,则只需要将上述代码中的 a[j] < a[k] 改为 a[j] > a[k]即 可。

将选择排序封装成函数,代码如下:

#include <stdio.h>

void selectSort(int arr[], int len);
void swap(int *a, int *b);
void printArray(int arr[], int len);

// 选择排序(升序)
void selectSort(int arr[], int len) {
	int i, j, min;
	for(i = 0; i < len; i++) {
		min = i; // 记录最小数下标
		for(j = i + 1; j < len; j++){ // 遍历剩余的数中,判断有没有更小的数,如果有则更改最小数的下标值
			if(arr[j] < arr[min]) {
				min = j;
			}
		}
		// 如果最小数的下标值发生变化,则交换两数
		if(min != i) {
			swap(&arr[i], &arr[min]);
		}
	}
}

// 两数交换
void swap(int *a, int *b) {
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

// 打印数组
void printArray(int arr[], int len) {
	int i;
	for(i = 0; i < 10; i++) {
		printf("%d ", arr[i]);
	}	
	printf("\n");
}

int main() {
	int a[] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
	int len = sizeof(a) / sizeof(int); // 数组长度
	printf("排序前:");
	printArray(a, len);
	selectSort(a, len);
	printf("排序后:");
	printArray(a, len);
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/578072.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

了解list

list 1. list的介绍及使用1.1 list的介绍1.2 list的使用1.2.1 list的构造1.2.2 list iterator的使用1.2.3 list capacity1.2.4 list element access1.2.5 list modifiers1. resize2. push_back/pop_back/push_front/pop_front3. insert /erase4. swap/clear 1.2.6 list operati…

chatgpt赋能python:Python中的数字转换

Python中的数字转换 在Python中&#xff0c;数字转换是一项非常基础但是非常重要的任务。无论您是在进行数据分析、机器学习还是编写Web应用程序&#xff0c;数字转换都是必不可少的。在这篇文章中&#xff0c;我们将介绍Python中的数字转换并提供一些实用的示例。 将字符串转…

Unity之SpriteShapeController

Detail&#xff1a;精灵形状的质量 高中低三种质量 Is Open Ended&#xff1a;是否是开放的&#xff0c;不封闭的 Adaptive UV&#xff1a;自适应UV&#xff0c;如果开启&#xff0c;会自动帮助我们判断是平铺还是拉伸 开启后只有宽度够才会平铺&#xff0c;如果宽度不够会拉…

micropython固件编译——把自己的py库添加进固件

目录 0. 前言1. 编写自己库的代码2. 移植库3. 验证 0. 前言 本节编译自己写的py库&#xff0c;增强移植性&#xff0c;往后烧录自己的固件即可轻易移植代码 没装好环境或者没有基础可以先看看这个&#xff1a; Ubuntu下ESP-IDF的环境搭建 Ubuntu下编译esp32micropython固件编…

antV 事件多次触发问题,解绑

由于最近刚刚接触 antV - 数据可视化,对于他的事件应用还比较陌生,在应用中莫名其妙多次调用,想了很多方式如节流……,但是没有用。 业务介绍 当我点击流程图中的某一项进行提示,每次双击都会递增调用。 解决过程 当时想着用节流的方式,但是很遗憾,他还是疯狂递增调用…

Go语言的命令

常用命令 假如你已安装了golang环境&#xff0c;你可以在命令行执行go命令查看相关的Go语言命令&#xff1a; Go语言是一门编译型语言&#xff0c;通过命令行工具来编译、运行和管理代码。以下是Go语言的一些常用命令及其用法&#xff1a; go run&#xff1a;用于编译并直接…

chatgpt赋能python:Python补全:介绍和优点

Python补全&#xff1a;介绍和优点 Python是一种高级编程语言&#xff0c;自20世纪90年代以来一直广受欢迎。Python被认为是一种非常易学易用的语言&#xff0c;因为它的代码看起来就像是英文一样流畅自然。它是一种解释性语言&#xff0c;这意味着代码可以直接在计算机上运行…

LeetCode 24. 两两交换链表中的节点

C代码&#xff1a; class Solution { public:ListNode* swapPairs(ListNode* head) {ListNode* dummyHead new ListNode(0);//设置一个虚拟头结点dummyHead->next head;// 将虚拟头结点指向head&#xff0c;这样方面后面做删除操作ListNode* cur dummyHead;//初始时&…

Android SharedPreferences转为MMKV

开篇 开局一张图&#xff0c;说明一切问题。 MMKV优势 可以看出MMKV相比SP的优势还是比较大的&#xff0c;除了需要引入库&#xff0c;有一些修改上的成本以外&#xff0c;就没有什么能够阻挡MMKV了。当然了&#xff0c;MMKV也有着不广为人知的缺点&#xff0c;放在最后。 MM…

【STM32F103ZE实验】【实验1】点亮LED

STM32CubeMx生成keil工程 步骤1&#xff1a;打开STM32CubeMx&#xff0c; 选择MCU类型 步骤2&#xff1a; 设置Debug类型 步骤3&#xff1a; 选择时钟源 步骤4&#xff1a; 配置时钟 步骤5&#xff1a; 配置GPIO控制LED 首先配置PE5 点击GPIO_Output进行相关配置&#…

如何使用Node.js REPL

目录 1、Nodejs REPL 2、_特殊变量 3、向上箭头键 4、点命令 5、从JavaScript文件运行REPL 1、Nodejs REPL REPL代表Read-Evaluate-Print-Loop&#xff0c;是交互式解释器。 node命令是我们用来运行Node.js脚本的命令&#xff1a; node script.js 如果我们运行node命令…

chatgpt赋能python:Python数据处理中如何选取指定范围的数据

Python数据处理中如何选取指定范围的数据 Python已经成为了数据科学家和工程师的标配&#xff0c;尤其在数据处理和数据分析中&#xff0c;Python具有广泛的应用。在数据处理中&#xff0c;选取指定范围的数据是一个很重要的功能。本文将介绍Python中如何实现指定范围的数据选…

SpringBoot——原理(起步依赖+自动配置(概述和案例))

在Spring家族中提供了很多优秀的框架&#xff0c;所有的框架都是基于同一个基础框架——Spring Framework. 使用spring框架开发麻烦的一批&#xff0c;光是搞依赖和配置就够人喝一壶了。因此在spring4.0版本之后又推出了springboot框架。springboot框架用起来比spring框架简单…

chatgpt赋能python:Python行长度的重要性及最佳实践

Python 行长度的重要性及最佳实践 Python 行长度的重要性 对于一门编程语言而言&#xff0c;行长度是指每一行代码的字符数&#xff0c;Python 也不例外。同时&#xff0c;Python 的行长度限制也是相当明确的&#xff0c;官方建议不要超过 79 个字符&#xff0c;而 PEP 8 规范…

【编译、链接、装载一】预处理、编译、汇编、链接

【编译和链接一】预处理、编译、汇编、链接 一、被隐藏了的过程二、预处理器&#xff08;Prepressing&#xff09;——cpp1、预处理指令2、预处理过程3、预处理生成的hello.i文件 三、编译器&#xff08;Compilation&#xff09;——cc1、编译指令2、编译的过程3、编译生成的文…

chatgpt赋能python:Python读取Mat文件的完整教程

Python 读取Mat文件的完整教程 在数据科学领域&#xff0c;Matlab&#xff08;或简称Mat&#xff09;是最受欢迎的编程语言之一。Matlab可用于数学计算、数据预处理、建模和数据分析。然而&#xff0c;Matlab的开销和许可证成本会限制公司和个人的使用。因此&#xff0c;Pytho…

渗透必学神器:BurpSuite教程(一)

0x00 前言 Burp Suite (简称BP&#xff0c;下同)是用于攻击web 应用程序的集成平台。它包含了许多工具&#xff0c;并为这些工具设计了许多接口&#xff0c;以促进加快攻击应用程序的过程。 从本节开始将为大家陆续带来BP各个模块的使用说明 0x01 中间人攻击 中间人攻击&am…

ChatGPT | Bing | Google Bard | 讯飞星火 | 到底哪家强?实测

最近AIGC战场依然热闹&#xff0c;微软的new bing、Google的Bard、国内的讯飞星火认知大模型&#xff0c;都接连上阵&#xff0c;我们对比ChatGPT一起来看看&#xff0c;我把实际使用测试结果发出&#xff0c;供大家参考。有些测试结果可能会出乎大家的预料哦… 今天我们暂时主…

第十四章 (Set)

一、Set 接口&#xff08;P518&#xff09; 1. Set 接口基本介绍 &#xff08;1&#xff09;无序&#xff08;添加和取出的顺序不一致&#xff09;&#xff0c;没有索引。 &#xff08;2&#xff09;不允许重复元素&#xff0c;所以最多包含一个 null。 2. Set 接口的常用方法…

阿里云服务器ECS云盘扩容

前言 对于云服务器&#xff0c;相信大多数开发的铁子们都玩过&#xff0c;但是云盘爆满的情况&#xff0c;对于新手或者没有自己运营业务的铁子们&#xff0c;平台给的初始容量也不算小&#xff0c;所以这种情况碰到的概率还是比较小。由于我的服务器应用的复杂度随着业务的发…