冒泡排序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了冒泡排序相关的知识,希望对你有一定的参考价值。

参考技术A 冒泡排序(Bubble Sort)是一种典型的交换排序算法,通过交换数据元素的位置进行排序。

一、算法基本思想

(1)基本思想

冒泡排序的基本思想就是:从无序序列头部开始,进行两两比较,根据大小交换位置,直到最后将最大(小)的数据元素交换到了无序队列的队尾,从而成为有序序列的一部分;下一次继续这个过程,直到所有数据元素都排好序。

算法的核心在于每次通过两两比较交换位置,选出剩余无序序列里最大(小)的数据元素放到队尾。

(2)运行过程

冒泡排序算法的运作如下:

1、比较相邻的元素。如果第一个比第二个大(小),就交换他们两个。

2、对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大(小)的数。

3、针对所有的元素重复以上的步骤,除了最后已经选出的元素(有序)。

4、持续每次对越来越少的元素(无序元素)重复上面的步骤,直到没有任何一对数字需要比较,则序列最终有序。

(3)示例

java 的如何实现冒泡算法呢?

其实有两种方法

一种是正序 

/*

* 正序冒泡

* */

public static void sortListAsc(Integer[] list)

if(list.length>0)

for(int i=0;i

for(int j=0;j

int exchange=0;

                if(list[j]>list[j+1])

exchange= list[j+1];

                    list[j+1]=list[j];

                    list[j]=exchange;

               







for(Integer k:list)

System.out.println(k);

   



一种是反序 

/*

* 反序冒泡

* */

public static void sortListDesc(Integer[] list)

if(list.length>0)

for(int i=(list.length-1);i>0;i--)

for(int j=(list.length-1);j>0;j--)

int a=0;

                      if(list[j]

a=list[j-1];

                          list[j-1]=list[j];

                          list[j]=a;

                     









虽然实现的目标是相同的,但是实现的原理也一样  只不过流程是逆向的      

完成之后便是如此   

如果使用Stiring 字符串的compareTo 也可以是实现类似功能  

不过这个比较的是字符串的ASCII码值的大小  ,可以应用于数字字符串的比较, 如此冒泡依旧可以使用。

//实现字符串的冒泡

public static String[]sortAscII(String[] list)

if(list.length>0)

for(int i=(list.length-1);i>0;i--)

for(int j=(list.length-1);j>0;j--)

String a="";

                if(list[j].compareTo(list[j-1])<0 )

a=list[j-1];

                    list[j-1]=list[j];

                    list[j]=a;

               







return list;

拓扑排序(图)、冒泡排序、插入排序

参考技术A AOV网络(Activity On Vertex)
拓扑序:如果在图中从V到W有一条有向路径,则V一定排在W之前。满足此条件的顶点序列称为一个拓扑序
获得一个拓扑序的过程就是拓扑排序
AVO如果有合理的拓扑序,则必定是有向无环图(Directed Acyclic Graph,DAG)
算法:
void TopSort ( )

for ( cnt = 0 ; cnt < [ V ] ; cnt ++ )
V = 未输出的入度为0的顶点 ;
if ( 这样的V不存在 )
Error ( “图中有回路” ) ;
break ;

输出V,或者纪录V的输出序号;
for ( V 的每个邻接点 W )
Indegree [ W ]--;



改进:随时将入度变为0的顶点放到一个容器里
void TopSort ( )

for ( 图中每个顶点 V )
if ( Indegree [ W ] == 0 )
Enqueue ( V , Q ) ;
while ( ! IsEmpty ( Q ) ) ;
V = Dequeue ( Q ) ;
输出V,或者纪录V的输出序号;
cnt ++; // 计数器,纪录顶点数量
for ( V 的每个邻接点 W )
if ( —Indegree [ W ] == 0 ) //如果减完后入度为0,则将其放入容器中
Enqueue ( W , Q ) ;

if ( cnt != [ V ] )
Error ( “图中有回路” );

时间复杂度 T = O( |V| + |E| )
此算法可以用来检测有向图是否DAG

关键路径问题
AOE(Activity On Edge)网络
一般用于安排项目的工序,活动表示在边上,顶点代表活动的停止;边上写有活动持续时间
顶点包括:顶点编号、最早完成时间、最晚完成时间

两类基础算法,排序和查找
排序算法的前提前提:
void X_Sort ( ElementType A [ ], int N )
1.大多数情况下,为简单起见,讨论从小到大的整数排序
2.N是正整数,只讨论基于比较的排序(> = < 是有定义的)
3.只讨论内部排序:内存空间充分大,排序在内部空间中完成
4.稳定性:任意两个相等的数据,排序前后的相对位置不发生改变
5.没有一种排序算法是任何情况下都表现最好的

void Bubble_Sort ( ElementType A[ ] , int N )

for ( P = N - 1 ; P >= 0 ; P — )
flag = 0 ;
for ( i = 0 ; i < p ; i ++ ) // 一趟冒泡
if ( A[ i ] > A[ i + 1 ] ) // 比较相邻两个元素的大小
Swap ( A[ i ] , A[ i + 1 ] ) ;
flag = 1 ; // 标识发生了交换

// 思考:假设当程序执行到某一步时 数据已经是有序的了,但此时程序是不知道的,所以还要判断
if ( flag == 0 ) break ; // 全程无交换 数据已经有序 不需要再进从排序


最好情况:顺序 T = O ( N )
最坏情况:逆序 T = O ( N的平方 )
由于是单向执行,比较相邻的两个元素,所以适用于链表存储的数据
当两个数据相等,冒泡排序的比较过程中没有将它们交换位置,所以改算法是稳定的

void Insertion_Sort ( ElementType A[ ] , int N )

for ( P = 1 ; P < N ; P ++ ) // 假设第0个元素已经存在,从第一个元素开始插入

Tmp = A[ P ] ; // 下一个元素
for ( i = P ; i > 0 && A[ i - 1 ] > Tmp ; i -- ) // 需要插入的新元素当前从最后那个元素开始比起,比到第一个元素
A[ i ] = A[ i - 1 ] ; // 移除空位
A[ i ] = Tmp ; // 新元素落位



最好情况:顺序 T = O ( N )
最坏情况:逆序 T = O ( N的平方 )
冒泡元素是两两交换 需要涉及到三步,插入排序元素向后错,新元素一次放入

逆序对:对于下标 i < j,如果A[ i ] > A[ j ],则称 ( i , j )是一对逆序对
每一次交换元素正好消去一个逆序对,序列中有多少个逆序对,就需要交换几次元素
时间复杂度下界:
插入排序:T( N , I ) = O( N + I ) 其中 I 是逆序对个数,如果序列基本有序,则插入排序简单且高效
定理:任意N个不同元素组成的序列平均有 N(N-1)/4 个逆序对。
定理:任何仅以交换相邻元素来排序的算法,其平均时间复杂度的下界为N平方
要提高算法效率,我们必须:每次交换不止消去一个逆序对,所以我们每次交换相隔较远的两个个元素

以上是关于冒泡排序的主要内容,如果未能解决你的问题,请参考以下文章

nodejs实现冒泡排序和快速排序

java编程的冒泡等排序示例

深度解析(十五)冒泡排序

冒泡排序

拓扑排序(图)、冒泡排序、插入排序

冒泡排序