排序算法-冒泡排序-选择排序


一、冒泡排序

1.原理

冒泡排序先会从头到尾比较相邻元素的⼤⼩,如果不满⾜升序降序的条件,则对其进⾏交换。⼀轮排序后,最⼤最⼩的元素将会移到末尾。因此进⾏ n-1 轮冒泡之后,整个序列即变为有序。
原理图

2.代码实现(降序排序)

#include <stdio.h>
void bubble_sort(int a[], int n) {
	int i, j;
	// 总共排序 n-1 轮
	for(i = 0; i < n - 1; i++)
	// j只需排到第 n-i 个元素,因为后i个元素已经有序
	for(j = 1; j < n - i; j++)
	// 如果不满⾜降序,则进⾏交换
	if(a[j] > a[j-1])
	{
	int temp = a[j];
	 a[j] = a[j-1];
	 a[j-1] = temp; 
	 } 
}
void print_array(int a[], int n) {
	int i;
	for(i = 0; i < n; i++)
		printf("%d ", a[i]);
	printf("\n");
	}
	
int main()
{
	int a[] = {7, 2, 3, 1, 5, 8, 9, 0, 4, 6};
	bubble_sort(a, 10);
	print_array(a, 10); // 输出排序后的数组
	return 0;
	}

如果需要升序排列,只需要将 if(a[j] > a[j-1]) 改为 if(a[j] < a[j-1]) 即可。

二、选择排序

1.原理

选择排序的原理是:先找到⽆序序列中的最⼤/最⼩元素的下标,然后将其与⽆序序列的第⼀个元素进⾏交换。这样序列的第⼀个元素就变为有序,之后我们需要对第⼀个元素后⾯的⽆序序列再进⾏选择排序。这样经过 n-1 轮,我们就得到了⼀个有序的序列。

例如序列 7, 2, 3, 1, 5, 8, 9, 0, 4, 6
我们先找到最⼤元素的下标为 6 ,将其与 a[0] 进⾏交换,便得到
 9, 2, 3, 1, 5, 8, 7, 0, 4, 6
这样,第⼀个元素便是有序的,我们只需要从 a[1] 开始再不断进⾏选择排序:
 9, 8, 3, 1, 5, 2, 7, 0, 4, 6
 9, 8, 7, 1, 5, 2, 3, 0, 4, 6
 9, 8, 7, 6, 5, 2, 3, 0, 4, 1
 9, 8, 7, 6, 5, 2, 3, 0, 4, 1
 …
 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
 这样最终我们就得到了有序序列。

2.代码实现(降序排序)

#include <stdio.h>

void select_sort(int a[], int n)
{
	int i, j;
	// 总共排序 n-1 轮
	for(i = 0; i < n - 1; i++) 
	{
		// 找到 i 之后的元素中最⼤元素的下标
		int max_j = i;
		for(j = i + 1; j < n; j++)
			if(a[j] > a[max_j])
				max_j = j;
		// 如果最⼤元素不为当前元素,则进⾏交换
		if(max_j != i) 
		{
			int temp = a[i];
			 a[i] = a[max_j];
			 a[max_j] = temp; 
		}
	} 
}


void print_array(int a[], int n) 
{
	int i;
	for(i = 0; i < n; i++)
		printf("%d ", a[i]);
	printf("\n");
}

int main()
{
	int a[] = {7, 2, 3, 1, 5, 8, 9, 0, 4, 6};
	select_sort(a, 10);
	print_array(a, 10); // 输出排序后的数组
	return 0; 
}

如果需要改为升序排列,我们只需先找到 i 及之后的最⼩元素的下标,再和 a[i] 进⾏交换即可。


注意事项

在排序算法中,有以下⼏点需要注意:

  1. 注意排序的内层循环变量 j 的起始值与终⽌条件
  2. 选择排列中,记录不是最⼤值⽽是最⼤元素的下标
  3. 对于结构体的排序,可以将中间变量 temp 定义为同⼀种结构体,这样就可以实现交换
  4. 对于字符串的排序,可以使⽤ strcpy 函数来实现交换
  5. 注意升序排列与降序排列的代码差别
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值