您的位置:首页 > 其它

内部排序之二:冒泡排序和选择排序(改进优化,附完整源码)

2014-03-10 17:24 453 查看

分类:
数据结构与算法 2014-03-02 09:36
1167人阅读 评论(12)
收藏
举报

冒泡排序选择排序改进优化

目录(?)[+]

转载请注明出处:/article/1337334.html

前言

之所以把冒泡排序和选择排序放在一起,是因为二者的实现代码很相似,而且都是最基本的排序方式,非常容易理解和实现。当然,如果仅仅是为了讲述这两种排序方式,那也根本没必要写这篇博文了。和上篇博文一样,我会在冒泡排序和选择排序原始代码的基础上给出一些改进和优化,这才是本文的重点所在。

原始冒泡排序

冒泡排序的思想很简单,如果要求排序后序列中元素按照从小到大的顺序排列,则冒泡排序的步骤如下:

1、依次比较序列中相邻的两个元素,将较大的放在后面,这样一趟比较后,最大的元素就放在了最后的一个位置;

2、再依次比较相邻的两个元素,将第二大的元素最终放到倒数第二个位置;

3、依次循环,直到最小的元素放在了第一个位置,排序完成。

根据以上思想,很容易写出代码:

[cpp]
view plaincopy





/*
冒泡排序后的顺序为从小到大
*/
void Bubble_Sort(int *arr,int len)
{
int i,j,exchange;
for(i=0;i<len-1;i++)
for(j=0;j<len-i-1;j++)
if(arr[j] > arr[j+1])
{
exchange = arr[j];
arr[j] = arr[j+1];
arr[j+1] = exchange;
}
}

改进冒泡排序

我们回过头来再来看上面冒泡排序的思想,无论原始序列的排序是怎样的(哪怕已经是从小到大排好的),它都要进行n-1趟比较,每趟比较又要进行n-i-1次相邻元素间的比较(i为从0开始计的第i趟比较),而实际上,很有可能还没有进行第n-1趟比较,已经完成了排序,这时候后面的几趟比较就显得多余了,基于此,我们可以做如下改进:设置一个标志位,如果某一趟有元素发生交换,则为true,继续下一趟比较,否则,说明排序已经完成,则标志位为false,退出循环。代码实现如下:

[cpp]
view plaincopy





/*
冒泡排序后的顺序为从小到大
*/
void Bubble_Sort(int *arr,int len)
{
int i,j,exchange;
bool flag = true; //增设标志位,判断是否已经完成排序
for(i=0; i<len-1 && flag; i++)
{
flag = false;
for(j=0;j<len-i-1;j++)
if(arr[j] > arr[j+1])
{ //如果本趟比较没有数据发生交换,说明排序已经完成
//则flag一直为false,从而退出循环,不再进行下一趟的比较
exchange = arr[j];
arr[j] = arr[j+1];
arr[j+1] = exchange;
flag = true;
}
}
}

直接选择排序

直接选择排序的思想也很简单,以排序从小到大为例,如下:

1、从第一个元素开始,选出一个最小的元素与第一个元素互换;

2、继续从第二个元素开始,向后选出最小的元素,与第二个元素互换;

3、依次循环执行,直到最大的元素放在了最后一个位置上,排序完成。

我们可以将第一个元素分别与后面的元素进行比较,遇到更小的,就交换,这样一趟比较下来,第一个元素保存就是最小值,而后再从第二个元素开似乎,依次与后面的元素比较,遇到更小的,就交换,这样,第二趟比较下来,第二个元素保存的就是第二小的值。。。依次循环执行,直到完成排序。按照这样的思路,实现代码如下:

[cpp]
view plaincopy





/*
第一种形式的选择排序
选择排序后的顺序为从小到大
*/
void Select_Sort1(int *arr,int len)
{
int i,j;
for(i=0;i<len;i++)
for(j=i+1;j<len;j++)
if(arr[i] > arr[j])
{
int exchange = arr[i];
arr[i] = arr[j];
arr[j] = exchange;
}
}

改进选择排序

但是我们上篇文章中提到过,在排序中应该尽量避免较多的和元素互换操作,而这里每比较一次,如果遇到更小的,就要互换一次元素。为了减少元素互换操作,我们可以在每次比较后不直接进行交换,将较小的元素的位置序号记录下来,这样一趟比较之后,就会得到最小元素的位置,如果最小值的位置发生了改变,再将该位置的元素与第一个元素互换,依次类推。。。这样每一趟比较完成后最多只需执行一次元素互换的操作。实现代码如下:

[cpp]
view plaincopy





/*
第二种形式的选择排序,减少了元素互换的操作
选择排序后的顺序为从小到大
*/
void Select_Sort2(int *arr,int len)
{
int i,j,min;
for(i=0;i<len;i++)
{
min = i; //用来记录每一趟比较的最小值的位置
for(j=i+1;j<len;j++)
if(arr[min] > arr[j])
min = j; //仅记录最小值的位置
//如果最小值的位置发生了变化,
//则最后执行一次元素互换的操作
if(min != i)
{
int exchange = arr[i];
arr[i] = arr[min];
arr[min] = exchange;
}
}
}

总结

冒泡排序和选择排序都是最基本的排序算法,平均时间复杂度都为O(n*n),排序元素个数较少时,适合使用,遇到大数据量时,最好选用其他排序算法。

完整源码

完整的C语言实现代码下载地址:http://download.csdn.net/detail/mmc_maodun/6970951
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐