内部排序之二:冒泡排序和选择排序

2024-09-02 06:08

本文主要是介绍内部排序之二:冒泡排序和选择排序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

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

原始冒泡排序

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

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

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

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

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

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
冒泡排序后的顺序为从小到大
*/
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,退出循环。代码实现如下:

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
冒泡排序后的顺序为从小到大
*/
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、依次循环执行,直到最大的元素放在了最后一个位置上,排序完成。

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

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
第一种形式的选择排序
选择排序后的顺序为从小到大
*/
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; 
            
}

改进选择排序


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

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
第二种形式的选择排序,减少了元素互换的操作
选择排序后的顺序为从小到大
*/
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

来源: csdn   作者:兰亭风雨  
源自:http://tech.ddvip.com/2014-03/1394804403209162.html

这篇关于内部排序之二:冒泡排序和选择排序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1129202

相关文章

Java List排序实例代码详解

《JavaList排序实例代码详解》:本文主要介绍JavaList排序的相关资料,Java排序方法包括自然排序、自定义排序、Lambda简化及多条件排序,实现灵活且代码简洁,文中通过代码介绍的... 目录一、自然排序二、自定义排序规则三、使用 Lambda 表达式简化 Comparator四、多条件排序五、

JAVA数组中五种常见排序方法整理汇总

《JAVA数组中五种常见排序方法整理汇总》本文给大家分享五种常用的Java数组排序方法整理,每种方法结合示例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录前言:法一:Arrays.sort()法二:冒泡排序法三:选择排序法四:反转排序法五:直接插入排序前言:几种常用的Java数组排序

Java中的内部类和常用类用法解读

《Java中的内部类和常用类用法解读》:本文主要介绍Java中的内部类和常用类用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录内部类和常用类内部类成员内部类静态内部类局部内部类匿名内部类常用类Object类包装类String类StringBuffer和Stri

exfat和ntfs哪个好? U盘格式化选择NTFS与exFAT的详细区别对比

《exfat和ntfs哪个好?U盘格式化选择NTFS与exFAT的详细区别对比》exFAT和NTFS是两种常见的文件系统,它们各自具有独特的优势和适用场景,以下是关于exFAT和NTFS的详细对比... 无论你是刚入手了内置 SSD 还是便携式移动硬盘或 U 盘,都需要先将它格式化成电脑或设备能够识别的「文

Mybatis 传参与排序模糊查询功能实现

《Mybatis传参与排序模糊查询功能实现》:本文主要介绍Mybatis传参与排序模糊查询功能实现,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、#{ }和${ }传参的区别二、排序三、like查询四、数据库连接池五、mysql 开发企业规范一、#{ }和${ }传参的

C++快速排序超详细讲解

《C++快速排序超详细讲解》快速排序是一种高效的排序算法,通过分治法将数组划分为两部分,递归排序,直到整个数组有序,通过代码解析和示例,详细解释了快速排序的工作原理和实现过程,需要的朋友可以参考下... 目录一、快速排序原理二、快速排序标准代码三、代码解析四、使用while循环的快速排序1.代码代码1.由快

Java捕获ThreadPoolExecutor内部线程异常的四种方法

《Java捕获ThreadPoolExecutor内部线程异常的四种方法》这篇文章主要为大家详细介绍了Java捕获ThreadPoolExecutor内部线程异常的四种方法,文中的示例代码讲解详细,感... 目录方案 1方案 2方案 3方案 4结论方案 1使用 execute + try-catch 记录

基于Python实现多语言朗读与单词选择测验

《基于Python实现多语言朗读与单词选择测验》在数字化教育日益普及的今天,开发一款能够支持多语言朗读和单词选择测验的程序,对于语言学习者来说无疑是一个巨大的福音,下面我们就来用Python实现一个这... 目录一、项目概述二、环境准备三、实现朗读功能四、实现单词选择测验五、创建图形用户界面六、运行程序七、

前端知识点之Javascript选择输入框confirm用法

《前端知识点之Javascript选择输入框confirm用法》:本文主要介绍JavaScript中的confirm方法的基本用法、功能特点、注意事项及常见用途,文中通过代码介绍的非常详细,对大家... 目录1. 基本用法2. 功能特点①阻塞行为:confirm 对话框会阻塞脚本的执行,直到用户作出选择。②

Spring排序机制之接口与注解的使用方法

《Spring排序机制之接口与注解的使用方法》本文介绍了Spring中多种排序机制,包括Ordered接口、PriorityOrdered接口、@Order注解和@Priority注解,提供了详细示例... 目录一、Spring 排序的需求场景二、Spring 中的排序机制1、Ordered 接口2、Pri