关于排序的浅理解---1.交换排序之冒泡排序

一、排序

关于排序,想必大家从字面意思就能理解,排序就是将一堆东西按照一定的规律摆放好位置。当然在计算机语言中,排序则是将一些数,字符,字符串等等数据按照程序员自定义的规则进行排列,而在计算机中又将排序分为两个大类:外排序和内排序

外部排序:数据量过大时,无法全部加载到内存中,需要借助外部储存进行排序。
内部排序:又称内排序,指将需要处理的所有数据都加载到内部储存中竞选排序。

外排序我们目前很少接触,主要接触到的还是内排序,而内排序又分出了如下几个小的排序方法:
在这里插入图片描述对于以上这些排序,目前我只做出简单的介绍,对于各排序以后的优化,我在之后的文章中会单独地进行描述。

首先先来讲讲交换排序中的冒泡排序
对于冒泡排序来说,顾名思义,就是像水中的气泡一样,大气泡的就往上浮,直至到达水面,然后破裂。而冒泡排序也是同理,通过最大的排序,将最大的数排到最后一位,然后第二大的数,到达次后位,以此类推…,通过多组遍历,直到将所有的数按从小到大的顺序排列出来,得到一个有序的数值序列,就将这样的排序方法称之为冒泡排序。由于冒泡排序中需要通过比较相邻两个数的大小,来判断是否需要进行交换,所以它属于交换排序。

冒泡排序的思路如下:

我们可以通过第一趟的冒泡排序的序列

int arr[] = {3,1,5,4,2};  //以这个数组为例
int temp = 0;   //设置临时变量,用来进行交换时,不同值的储存
for(int j = 0;j < a.length - 1 - 0;j++)     //此处的 0 为今后的i值,因为i控制着遍历的次数
			{
				if(a[j] > a[j+1])
				{
					temp = a[j+1];
					a[j+1] = a[j];
					a[j] = temp;
				}
			}

①第一趟排序过后的序列为:{1,3,4,2,5};
可以看出第一次的排序是将数组中的0号位置与1号位置的值进行了比较,通过判断,这两个值需要进行交换,所以得到了如上序列。在for循环中可以注意到a.length - 1 - 0,在 0 这个地方需要注意,因为此处今后作为i值,来控制交换排序所需要遍历的次数。
我们可以查看第二趟排序的序列

for(int j = 0;j < a.length - 1 - 1;j++)     //此处 0 位置 变成了 1
			{
				if(a[j] > a[j+1])
				{
					temp = a[j+1];
					a[j+1] = a[j];
					a[j] = temp;
				}
			}

②第二趟排序过后的序列为:{1,3,2,4,5}
而第三趟排序,就已经达到了有序

for(int j = 0;j < a.length - 1 - 2;j++)     //此处 1 位置 变成了 2
			{
				if(a[j] > a[j+1])
				{
					temp = a[j+1];
					a[j+1] = a[j];
					a[j] = temp;
				}
			}

③第三趟排序过后的序列为:{1,2,3,4,5}
可以看出在第三次排序过后,它将数按从小到大都依次排列好了,然后显示出来的就是一个有序的序列,所以可以从此看出规律:每次进行遍历时,范围发生了改变,第一趟排序时,j的遍历范围小于a.length - 1 - 0,第二趟排序时,j的遍历范围小于a.length - 1 - 1,第三趟排序时,j的遍历范围小于a.length - 1 - 2,…,所以第 i 趟排序,j的遍历范围应是小于a.length - 1- i;而在这个地方我们可以用一个大的for循环,把这个for循环嵌套在大的for循环之内,这样就可以达到不需人为输入去改变每次的排序,而是通过这个大的for循环将整个循环遍历

所以完整的代码如下:

public static void BubbleSort(int a[]) {
		int temp = 0;
		for(int i = 0;i < a.length - 1;i++)
		{
			for(int j = 0;j < a.length - 1 - i;j++)
			{
				if(a[j] > a[j+1])
				{
					temp = a[j+1];
					a[j+1] = a[j];
					a[j] = temp;
				}
				
			}
		}
}

虽然说它在第三次时,就将这个整数序列排好序了,可是它真正的排序次数可是大于3次的,那么怎么让这个算法,不会浪费多余的次数,而有效地进行呢?

我们可以在一开始设置一个标志位flag,来判断是否进行了交换,如果进行了交换,它就发生改变,来反馈数之间进行了交换,若没改变,则结束循环,来达到减少非必要循环的次数。可在for循环里,加入一个判断flag是否改变。
具体如下:

public static void BubbleSort(int a[]) {
		int temp = 0;
		int flag = 0;
		
		for(int i = 0;i < a.length - 1;i++)
		{
			for(int j = 0;j < a.length - 1 - i;j++)
			{
				if(a[j] > a[j+1])
				{
					temp = a[j+1];
					a[j+1] = a[j];
					a[j] = temp;
					flag = 1;
				}
				
			}
			if(flag == 0)
			{
				break;
			}
			else
			{
				flag = 1;
			}
		}
	}

也可以在 i 的那一层for循环中,设置flag,但是你在进行每一次for循环时,都会创造一个flag的空间,所以我将flag放在了最外面,而是在里面对flag进行判断。

在此给出一个实例方便理解,从键盘输入n个数,然后将这n个数进行冒泡排序(我是用Java实现的,c++和c大同小异)

package 冒泡排序;
import java.io.*;
import java.util.Arrays;


public class Main {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String n = in.readLine();
		String s[] = in.readLine().split(" ");
		int a[] = new int[Integer.parseInt(n)];
		for(int i = 0;i < Integer.parseInt(n);i++)
		{
			a[i] = Integer.parseInt(s[i]);
		}
		BubbleSort(a);
		for(int i = 0;i < a.length;i++)
		{
			System.out.print(a[i] + " ");			
		}
		
		in.close();
	}
	

	public static void BubbleSort(int a[]) {
		int temp = 0;
		for(int i = 0;i < a.length - 1;i++)
		{
			for(int j = 0;j < a.length - 1 - i;j++)
			{
				if(a[j] > a[j+1])
				{
					temp = a[j+1];
					a[j+1] = a[j];
					a[j] = temp;
				}
			}
		}
	}
	
}

至于例子中所采用的就是冒泡排序,我对于这个排序法的理解,大致就是这样,请各位道友,如有更好的见解以及更深的理解,可私信我进行探讨。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值