冒泡排序法和选择排序法(C语言)

冒泡排序法

一、冒泡排序就是不断“挪数到最后”

按照从小到大的顺序用冒泡排序法如图:

  1. 在数组所有数中,把数值最大的挪到最后(红色箭头位置):
    在这里插入图片描述

  2. 在剩下的数中(蓝色圈里的),把数值最大的挪到最后(红色箭头位置):
    在这里插入图片描述

  3. 继续在剩下的数中(蓝色圈里的),把数值最大的挪到最后(红色箭头位置):
    在这里插入图片描述

  4. 然后一直重复……

  5. 到只剩下两个的时候即为排序的最后一次,这次完成后数组首个数值也会跟着定下来:
    在这里插入图片描述

现在研究一下,“把数值最大的挪到最后”这个操作要执行几次:
如果数组只有1个元素,就不用排序了
如果数组有2个元素,挪数的操作需要1次
如果数组有3个元素,挪数的操作需要2次
如果数组有4个元素,挪数的操作需要3次
……
可以推出:如果数组有n个元素,挪数的操作需要n-1次。

二、如何实现“把数挪到最后”

  1. 如何在数组所有元素(蓝色圈里的)中,把数值最大的挪到最后(红色箭头位置)
    在这里插入图片描述
    先看数组第1个元素(数组[0]),拿它和它后面的元素(数组[1])做比较:
    在这里插入图片描述

    • 如果数组[0]>数组[1],就交换它俩的数值,保证后面的元素的数值要比前面的大。
    • 如果数组[0]<=数组[1],就不用管它们。

    然后接着看数组第2个元素(数组[1]),拿它和它后面的元素(数组[2])做比较:
    在这里插入图片描述

    • 如果数组[1]>数组[2],就交换它俩的数值,保证后面的元素的数值要比前面的大。
    • 如果数组[1]<=数组[2],就不用管它们。

    再继续接着看数组第3个元素(数组[2]),拿它和它后面的元素(数组[3])做比较:
    在这里插入图片描述
    一直重复……,当看到数组倒数第二个元素时就是最后一次:
    在这里插入图片描述

假设这个数组有n个元素,在这一轮中,从数组第一个元素(数组[0])开始看,看到数组倒数第二个元素,总共看了n-1个元素

  1. 如何在数组剩下的数(蓝色圈里的)中,把数值最大的挪到最后(红色箭头位置):
    在这里插入图片描述
    先看数组第1个元素(数组[0]),拿它和它后面的元素(数组[1])做比较;
    然后接着看数组第2个元素(数组[1]),拿它和它后面的元素(数组[2])做比较;
    再继续接着看数组第3个元素(数组[2]),拿它和它后面的元素(数组[3])做比较;
    一直重复……,当看到蓝色圈里的倒数第二个元素时就是最后一次:
    在这里插入图片描述

这一轮中,从数组第一个元素(数组[0])开始看,看到数组倒数第三个元素,总共看了n-2个元素

  1. 用上述方法继续确定数组倒数第三元素的值、倒数第四元素的值、……
  2. 一直到数组第二元素的值被确定下来,整个冒泡排序法就完成了。

三、小例子

用冒泡排序法对数组int data[]={12,8,13,9}排序(从小到大)

#include <stdio.h>
int main(void)
{
	int data[] = {12,8,13,9};
	int ArrayLength = sizeof(data)/sizeof(data[0]);//求数组长度(数组有多少个元素)
	int temp;
	for(int i=0; i<ArrayLength-1; i++)
	{
		for(int j=0; j<ArrayLength-1-i; j++)
		{
			if(data[j] > data[j+1])
			{
				temp = data[j];
				data[j] = data[j+1];
				data[j+1] = temp;
			}
		}
	}
	for(int i=0; i<ArrayLength; i++)
	{
		printf("%d  ",data[i]);
	}
	return 0;
}
  1. i=0:

    1. j=0,看data[0],拿它和它后面的元素data[1]比较

      12>8,互换它俩的位置,此时数组data的顺序为:8、12、13、9

    2. j=1,看data[1],拿它和它后面的元素data[2]比较

      12<13,不用管它俩,此时数组data的顺序为:8、12、13、9

    3. j=2,看data[1],拿它和它后面的元素data[2]比较

      13>9,互换它俩的位置,此时数组data的顺序为:8、12、9、13

  2. i=1:

    1. j=0,看data[0],拿它和它后面的元素data[1]比较

      8<12,不用管它俩,此时数组data的顺序为:8、12、9、13

    2. j=1,看data[1],拿它和它后面的元素data[2]比较

      12>9,互换它俩的位置,此时数组data的顺序为:8、9、12、13

  3. i=2:

    1. j=0,看data[0],拿它和它后面的元素data[1]比较

      8<9,不用管它俩,此时数组data的书序为:8、9、12、13

用表格的形式来看,从小到大用冒泡排序法对数组int data[]={12,8,13,9}排序:

j=0j=1j=2
i=08、12、13、98、12、13、98、12、9、13最后一个元素值最大确定为13
i=18、12、98、9、12倒数第二个元素值最大确定为12
i=28、9倒数第三个元素值最大确定为9

简单选择排序法

一、选择排序就是不断“找数比较”

按照从小到大的顺序用冒泡排序法如图:

  1. 看数组第一个元素,拿它的数值和数组其它元素的数值(蓝色圈里的)做比较,如果发现有比它大的,就交换它俩的数值,确保第一个元素的值在所有元素中是最小的
    在这里插入图片描述

  2. 看数组第二个元素,拿它的数值和数组其它元素的数值(蓝色圈里的)做比较,如果发现有比它大的,就交换它俩的数值,确保第二个元素的值比蓝色圈里的都要小
    在这里插入图片描述

  3. 看数组第三个元素,拿它的数值和数组其它元素的数值(蓝色圈里的)做比较,如果发现有比它大的,就交换它俩的数值,确保第三个元素的值比蓝色圈里的都要小
    在这里插入图片描述

  4. 然后一直重复……

  5. 最后一次是用数组倒数第二个元素和倒数第一个元素做比较,比较完这次后就结束
    在这里插入图片描述

如果数组有只有1个元素,就不用排序了
如果数组有2个元素,就需要看数组第一个元素,总共1次
如果数组有3个元素,就需要看数组第一、二个元素,总共2次
如果数组有4个元素,就需要看数组第一、二、三个元素,总共3次
……
可以推出:如果数组有n个元素,就需要看数组第一、二、三、……n-1个元素,总共n-1次

二、如何“比较”

  1. 看数组第一个元素数组[0],如何拿它的数值和数组其它元素的数值(蓝色圈里的)做比较,以确保它的值在所有元素中是最小的
    在这里插入图片描述
    先拿数组第二个元素数组[1]和数组第一个元素数组[0]作比较
    在这里插入图片描述

    • 如果数组[0]>数组[1],就交换它俩的数值,保证数组[0]的数值是最小的。
    • 如果数组[0]<=数组[1],就不用管它们。

    再拿数组第三个元素数组[2]和数组第一个元素数组[0]作比较
    在这里插入图片描述

    • 如果数组[0]>数组[2],就交换它俩的数值,保证数组[0]的数值是最小的
    • 如果数组[0]<=数组[2],就不用管它们

    一直拿数组第四个、第五个、……到数组最后一个元素,来和数组第一个元素数组[0]作比较
    在这里插入图片描述
    比较完就能保证数组第一个元素数组[0]的值是最小的。

  2. 继续看数组第二个元素数组[1],从数组第三个元素数组[2]开始和它做比较
    在这里插入图片描述

    • 如果数组[1]>数组[2],就交换它俩的数值
    • 如果数组[1]<=数组[2],就不用管它们

    然后拿数组第四个、第五个、……到数组最后一个元素,来和数组第二个元素数组[1]作比较
    在这里插入图片描述

  3. 用上述方法一直确定数组第三个元素、第四个元素……

  4. 一直到确定完数组倒数第二个元素,整个简单选择排序法就完成了

三、小例子

用选择排序法对数组int data[]={12,8,13,9}排序(从小到大)

#include <stdio.h>
int main(void)
{
	int data[] = {12,8,13,9};
	int ArrayLength = sizeof(data)/sizeof(data[0]);
	int temp;
	for(int i=0; i<ArrayLength-1; i++)
	{
		for(int j=i+1; j<ArrayLength; j++)
		{
			if(data[i] > data[j])
			{
				temp = data[i];
				data[i] = data[j];
				data[j] = temp;
			}
		}
	}
	for(int i=0; i<ArrayLength; i++)
	{
		printf("%d  ",data[i]);
	}
	return 0;
}
  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值