数据结构复习之内排序(1)---插入排序、冒泡排序、选择排序

【主要内容】插入排序、冒泡排序、选择排序的通俗易懂的解释;插入排序、冒泡排序、选择排序的代码(一律用java演示);插入排序、冒泡排序、选择排序的对比。

一、插入排序

1.通俗易懂的解释

举个例子,假如说你和你的朋友正在玩斗地主,你朋友发牌,你一张一张拿牌,拿一张牌就要把它放在手里合适的位置。假设你喜欢从小到大放,那么他给你发一张牌,你只需要把这张牌和你手中已经排好序的牌组两两作比较,插入到合适的位置中(当然眼尖的一般就直接插到排好序的牌组里了)。这就是插入排序,即每次都要遍历这个数组,从前往后把待排序的号插到前面已经排好的数组中,前面已排好的序列永远是有顺序的。

2.什么?没懂?那画个图康康

3.还没懂?那来看代码吧

package sort;

import java.util.Arrays;

public class Insort {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a[] = new int[8];
			a[0]=42;
			a[1]=20;
			a[2]=17;
			a[3]=13;
			a[4]=28;
			a[5]=14;
			a[6]=23;
			a[7]=15;
		a = innsort(a);
	}
	static int[] innsort(int a[])
	{
		int n = a.length;
		int tem[] = new int[2];
		for(int i=1;i<n;i++)
		{
			for(int j=i;j>0&&prior(a[j],a[j-1]);j--)
			{
				tem = swap(a[j],a[j-1]);
				a[j] = tem[0];
				a[j-1] = tem[1];
			}
			System.out.println("现在是第"+i+"次排序,排序结果如下:");
			System.out.println(Arrays.toString(a));
		}
		return a;
	}
	static Boolean prior(int a,int b)
	{
		return a<b;
	}
	static int[] swap(int a,int b)
	{
		int tem = a;
		a = b;
		b = tem;
		return new int[]{a,b};
	}
}

输出结果:

现在是第1次排序,排序结果如下:
[20, 42, 17, 13, 28, 14, 23, 15]
现在是第2次排序,排序结果如下:
[17, 20, 42, 13, 28, 14, 23, 15]
现在是第3次排序,排序结果如下:
[13, 17, 20, 42, 28, 14, 23, 15]
现在是第4次排序,排序结果如下:
[13, 17, 20, 28, 42, 14, 23, 15]
现在是第5次排序,排序结果如下:
[13, 14, 17, 20, 28, 42, 23, 15]
现在是第6次排序,排序结果如下:
[13, 14, 17, 20, 23, 28, 42, 15]
现在是第7次排序,排序结果如下:
[13, 14, 15, 17, 20, 23, 28, 42]

4.时间复杂度分析

可以看到,主要影响代码运行速度的是innsort方法。在最差情况下(即原先数组是逆序的),他需要每一个元素都要进行比较和交换,所以时间复杂度为Θ(n²),在最佳情况下(即数组已经排好序了),他不需要进内层for循环,故时间复杂度为Θ(n),平均下来则为Θ(n²)

二、冒泡排序

1.通俗易懂的解释

冒泡排序其实这里是不太好理解的,这样吧我说一遍过程,结合下图看食用效果更佳。遍历整个数组(从后往前,这里和插入排序不一样,插入排序是从前往后,切记不要弄混),只要后面的比前面的元素小,就把小的换到前面去,直到前面的和他一样或者比他小,就停止冒这个元素。然后继续把他前面的元素往前冒,如下图所示(小泡表示值小,大泡表示值大)

2.什么?没懂?那画个图康康

 

也就是说最小元素第一次就被推到了整个数组的最上面。

3.还没懂?那来看代码吧

package sort;

import java.util.Arrays;

public class Bubsort {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a[] = new int[8];
			a[0]=42;
			a[1]=20;
			a[2]=17;
			a[3]=13;
			a[4]=28;
			a[5]=14;
			a[6]=23;
			a[7]=15;
		System.out.println("排序前:");
		System.out.println(Arrays.toString(a));
		a = bubsort(a);
	}

	private static int[] bubsort(int[] a) {
		// TODO Auto-generated method stub
		int n = a.length;
		int tem[] = new int[2];
		for(int i=0;i<n-1;i++)
		{
			for(int j=n-1;j>i;j--)
			{
				if(prior(a[j],a[j-1]))//j比j-1要小
				{
					tem = swap(a[j],a[j-1]);
					a[j] = tem[0];
					a[j-1] = tem[1];
				}
			}
			System.out.println("现在是第"+(i+1)+"次排序,排序结果如下:");
			System.out.println(Arrays.toString(a));
		}
		return a;
	}
	static Boolean prior(int a,int b)
	{
		return a<b;
	}
	static int[] swap(int a,int b)
	{
		int tem = a;
		a = b;
		b = tem;
		return new int[]{a,b};
	}
}

输出结果:

排序前:
[42, 20, 17, 13, 28, 14, 23, 15]
现在是第1次排序,排序结果如下:
[13, 42, 20, 17, 14, 28, 15, 23]
现在是第2次排序,排序结果如下:
[13, 14, 42, 20, 17, 15, 28, 23]
现在是第3次排序,排序结果如下:
[13, 14, 15, 42, 20, 17, 23, 28]
现在是第4次排序,排序结果如下:
[13, 14, 15, 17, 42, 20, 23, 28]
现在是第5次排序,排序结果如下:
[13, 14, 15, 17, 20, 42, 23, 28]
现在是第6次排序,排序结果如下:
[13, 14, 15, 17, 20, 23, 42, 28]
现在是第7次排序,排序结果如下:
[13, 14, 15, 17, 20, 23, 28, 42]

4.时间复杂度分析

可以看到,主要影响代码运行速度的是bubsort方法。不管在最好最差平均情况下他都要进内循环,故复杂度为Θ(n²)

三、选择排序

1.通俗易懂的解释

这个就比较好解释了,还是拿插入排序的例子来讲,你和你朋友玩斗地主,但是这回不是发一张牌就拿一张,你是等发完牌了之后把所有牌拿起来之后整理。还是从小到大排序,这次你是选一张牌出来之后插到之前已经排好序的牌堆里。这就是选择排序。在第i次排序的时候,把未排序的里面号出来此时最小的放在第i的位置上,这个时候0~i的位置已经是整个排序序列里第0、1、2、...i小的元素。它的比较次数和冒泡一样,交换次数却只有(n-1)次。

2.什么?没懂?那画个图康康(我觉得这个就不用画图康康了吧,好吧其实是我不想画了)

假装这里有图

3.还没懂?那来看代码吧

package sort;

import java.util.Arrays;

public class Selsort {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a[] = new int[8];
		a[0]=42;
		a[1]=20;
		a[2]=17;
		a[3]=13;
		a[4]=28;
		a[5]=14;
		a[6]=23;
		a[7]=15;
		System.out.println("排序前:");
		System.out.println(Arrays.toString(a));
		a = selsort(a);
	}
	private static int[] selsort(int[] a) {
		// TODO Auto-generated method stub
		int n = a.length;
		int lowindex=0;
		int tem[] = new int[2];
		for(int i=0;i<n-1;i++)
		{
			lowindex=i;
			for(int j=i+1;j<n;j++)//从后往前找
			{
				if(prior(a[j], a[lowindex]))
				{
					lowindex = j;
				}
			}
			tem = swap(a[i],a[lowindex]);
			a[i] = tem[0];
			a[lowindex] = tem[1];
			System.out.println("现在是第"+(i+1)+"次排序,排序结果如下:");
			System.out.println(Arrays.toString(a));
		}
		return a;
	}
	static Boolean prior(int a,int b)
	{
		return a<b;
	}
	static int[] swap(int a,int b)
	{
		int tem = a;
		a = b;
		b = tem;
		return new int[]{a,b};
	}
}

输出结果:

排序前:
[42, 20, 17, 13, 28, 14, 23, 15]
现在是第1次排序,排序结果如下:
[13, 20, 17, 42, 28, 14, 23, 15]
现在是第2次排序,排序结果如下:
[13, 14, 17, 42, 28, 20, 23, 15]
现在是第3次排序,排序结果如下:
[13, 14, 15, 42, 28, 20, 23, 17]
现在是第4次排序,排序结果如下:
[13, 14, 15, 17, 28, 20, 23, 42]
现在是第5次排序,排序结果如下:
[13, 14, 15, 17, 20, 28, 23, 42]
现在是第6次排序,排序结果如下:
[13, 14, 15, 17, 20, 23, 28, 42]
现在是第7次排序,排序结果如下:
[13, 14, 15, 17, 20, 23, 28, 42]

4.时间复杂度分析

可以看到,主要影响代码运行速度的是selsort方法。不管在最好最差平均情况下他都要进内循环,故复杂度为Θ(n²)。

四、三种排序对比

看表就完事

插入排序、冒泡排序、选择排序复杂度比较
 插入排序冒泡排序选择排序
比较情况   
最佳情况Θ(n)Θ(n²)Θ(n²)
平均情况Θ(n²)Θ(n²)Θ(n²)
最差情况Θ(n²)Θ(n²)Θ(n²)
交换情况   
最佳情况00Θ(n)
平均情况Θ(n²)Θ(n²)Θ(n)
最差情况Θ(n²)Θ(n²)Θ(n)

 

【絮絮叨叨】近期会不定期更新数据结构、操作系统、java的一些知识点总结,敬请期待。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值