您的位置:首页 > 其它

三种基础排序(冒泡、选择、插入排序)

2016-10-22 15:36 155 查看
这是本人的第一篇博客,看了刘未鹏大神的《暗时间》,想想还是应该写点博客,虽然内容都是从比人那里学来的,但是用自己的话去再诠释一遍,可能会有意外的收获。

好了,废话就到这里了,下面开始用最简单的方式介绍这三种排序吧。

1、冒泡排序

冒泡排序的过程,就是将数组里面的元素不断向后冒,一趟下来,最大的冒到了最后。这样说也许很不生动形象,来举一个例子就明白了。

a[ ] = {1,4,2,6,2,4};我们打算把大的元素冒后数组后面去:

第一次:a[ ] = {1,4,2,6,2,4} 接下来a[0]与a[1]进行比较,1<4 所以我们从4开始冒泡(如果前面的数小于后面的数,那么接着从大的数开始冒泡)

第二次:a[ ] = {1,4,2,6,2,4} 接下来a[1]与a[2]进行比较,4>2 所以交换位置后:a[ ] = {1,2,4,64,2,4} 

第三次:a[ ] = {1,2,4,6,2,4} 接下来a[2]与a[3]进行比较,4<6 所以不用交换位置:a[ ] = {1,2,4,6,2,4} 

第四次:a[ ] = {1,2,4,6,2,4} 接下来a[3]与a[4]进行比较,6>2 所以交换位置:a[ ] = {1,2,4,2,6,4} 

第四次:a[ ] = {1,2,4,2,6,4}
接下来a[4]与a[5]进行比较,6>4 所以交换位置:a[ ] = {1,2,4,2,4,6} 
这样,相当于遍历一次数组,就把最大的6冒到最后了。

接下来又从a[0]开始冒泡,

第二次遍历的结果:a[ ] = {1,2,2,4,4,6} 

第三次遍历结果:a[ ] = {1,2,2,4,4,6} 没有交换,说明已经排好序了。

<
c364
/span>

我们来看看代码,以java语言为例:

public static void bubbleSort(int a[],int size){

int temp;//用于交换的临时变量
boolean change = false;//用来判断是否提前排好序
//第一层循环 说明要进行size次
for(int i =0;i<size;i++){
// j<size-i 是说明不用每次都冒泡到最后一个位置
// 冒泡到无序的最后就好   已经冒泡上去的都是有序的
//如果size-i会指针越界  因为下面要进行a[j]与a[j+1]的比较
for(int j=0;j<size-i-1;j++){
if(a[j]>a[j+1]){
temp = a[j+1];
a[j+1] = a[j];
a[j] = temp;
change = true;
}
}
if(!change){
break;//没有交换数据  说明已经排好序了
}
}
}


相信大家都很容易看懂这段代码,可以不设置change这个标记值。

2.选择排序

选择排序,顾名思义就是每次选择一个最小或者最大的数,选择n次后,就可以排好序了。

还是以a[ ] = {1,4,2,6,2,4};为例,我们每次选择最小的,然后把前面的与最小的交换位置。

第一次选择从a[0] 到a[5]:最小的数:1 下标为0 交换a[0]与a[0]的元素a[ ] = {1,4,2,6,2,4};

第二次选择从a[1] 到a[5]:最小的数:2 下标为4 交换a[1]与a[4]的元素a[ ] = {1,2,2,6,4,4};

第三次选择从a[2] 到a[5]:最小的数:2 下标为2 交换a[2]与a[2]的元素 a[ ] = {1,2,2,6,4,4};

第四次选择从a[3] 到a[5]:最小的数:4 下标为5 交换a[3]与a[5]的元素 a[ ] = {1,2,2,4,4,6};

第五次选择从a[4] 到a[5]:最小的数:4 下标为4 交换a[4]与a[4]的元素 a[ ] = {1,2,2,4,4,6};
这样就排好序了,很简单吧。

来看看代码:
public static void selectSort(int a[] ,int size){

int index; //保存最小数的下标
int min;//保存最小的数

for(int i=0;i<size-1;i++){
min = a[i];//每次初始前面的第一个数为最小的
index = i; //最小的下标
//寻找最小的数据并且记录下来下标
for(int j=i;j<size;j++){
if(a[j]<=min){
min = a[j];
index = j;
}
}
//交换数据
a[index] = a[i];
a[i] = min;
}
}


代码也很简单,相信初学者看起来并没有难度。

3、插入排序
插入排序比上面两个复杂一点。插入排序就像是抽扑克牌,给扑克牌排序。我们会右手新起的扑克牌插入到左手有序的扑克牌合适的位置,这个过程就是插入排序的基本思想了。
还有一个例子,插入排序就相当于生活中的插队,你要插入一个排好的队伍里面,由于空间不够,所以每个人要向后退后一个身位给你插入(如果他们乐意让你插队的话)。
还是这个例子a[ ] = {1,4,2,6,2,4}; 首先,我们把a[0]当做一个有序的(不用当做,因为它就是有序的)。
然后开始插入,首先,将a[1]即把4插入到前面的有序数组,我们要找一个合适的位置插入4,我们可以从4所在的位置向前比较,直到a[i]<=4为止,那么a[i+1]就是合适的位置了。
我们发现a[1]现在的位置就是合适的位置。所以不用变化。
a[ ] = {1,4,2,6,2,4};

接着我们将a[2]插入到前面,我们发现a[2]应该插入到a[1]的位置,把原来的a[1]向后移动。
a[ ] = {1,2,4,6,2,4};

然后把a[3]插入到前面有序的数组,发现位置不用变。
a[ ] = {1,2,4,6,2,4};

然后把a[4]插入到前面有序的数组,发现位置应该变到a[2],然后把有序数组往后移动一个位置。
a[ ] = {1,2,2,4,6,4};

然后把a[5]插入到前面有序的数组,发现位置应该变到a[4],然后把有序数组往后移动一个位置。
a[ ] = {1,2,2,4,4,6};

也许你有一个疑问,该如何全部向后移动一个位置呢?

这个可以看看代码
public static  void insertSort(int[]a ,int size){
int temp ;//保存待插入的数
int index ; //保存合适保存的位置
for(int i=1;i<size;i++){
temp = a[i];
index = i;
for(int j=i-1;j>=0;j--){
if(a[j]<temp) break;
}
//把数据向后移动
for(int j=i;j>index;j--){
a[j] = a[j-1];
}
a[index] = temp;
}
}


这个是先找到合适的位置,然后开始移动数据,其实我们可以把这两步合起来。
public static  void insertSort(int[]a ,int size){
int temp ;//保存待插入的数
int index ; //保存合适保存的位置
for(int i=1;i<size;i++){
temp = a[i];
index = i;
for(int j=i-1;j>=0;j--){
if(a[j]<temp) break; //之前一次循环已经找到了最佳位置

index = j;
a[j+1] = a[j];//向后移动数据
}
a[index] = temp;//把数据赋值到合适位置
}
}


不难发现,这三种基础排序算法都是嵌套的for循环,时间复杂度是O(n^2),在数据量较小的时候,是可以用这个几个排序的,平均情况下其中的插入排序较好。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: