利用冒泡排序对数组进行排序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
利⽤冒泡排序对数组进⾏排序
⼀、冒泡排序:
利⽤冒泡排序对数组进⾏排序
⼆、基本概念:
依次⽐较相邻的两个数,将⼩数放在前⾯,⼤数放在后⾯。
即在第⼀趟:⾸先⽐较第1个和第2个数,将⼩数放前,⼤数放后。
然后⽐较第2个数和第3个数,将⼩数放前,⼤数放后,如此继续,直⾄⽐较最后两个数,将⼩数放前,⼤数放后。
⾄此第⼀趟结束,将最⼤的数放到了最后。
在第⼆趟:仍从第⼀对数开始⽐较(因为可能由于第2个数和第3个数的交换,使得第1个数不再⼩于第2个数),将⼩数放前,⼤数放后,⼀直⽐较到倒数第⼆个数(倒数第⼀的位置上已经是最⼤的),第⼆趟结束,在倒数第⼆的位置上得到⼀个新的最⼤数(其实在整个数列中是第⼆⼤的数)。
如此下去,重复以上过程,直⾄最终完成排序。
三、实现思路:
⽤⼆重循环实现,外循环变量设为i,内循环变量设为j。
假如有n个数需要进⾏排序,则外循环重复n-1次,内循环依次重复n-1,n-2,...,1次。
每次进⾏⽐较的两个元素都是与内循环j有关的,它们可以分别⽤a[j]和a[j+1]标识,i的值依次为
1,2,...,n-1,对于每⼀个i,j的值依次为0,1,2,...n-i 。
设数组长度为N:
1.⽐较相邻的前后⼆个数据,如果前⾯数据⼤于后⾯的数据,就将⼆个数据交换。
2.这样对数组的第0个数据到N-1个数据进⾏⼀次遍历后,最⼤的⼀个数据就“沉”到数组第N-1个位置。
3.N=N-1,如果N不为0就重复前⾯⼆步,否则排序完成。
四、java代码实现:
[java]
package ArrayDemo;
/**
* @author pplsunny
* @category .21
*/
public class ArrayDemo {
/**
* ⽤增强for循环输出排序结果
*/
public static void main(String[] args) {
int[] a = { 2, 4, 76, 12, 34, 23, 86 };
ArrayDemo.bubbleSort(a);
for (int b : a) {
System.out.print(b + " ");
}
}
/*
* 冒泡排序函数,定义为静态的⽅便使⽤,也是开发中定义⼯具类的⼀个⽅法
*/
public static void bubbleSort(int a[]) {
for (int i = 1; i < a.length; i++) { //这是控制趟数
for (int j = 0; j < a.length - i; j++) { //j < a.length - i,⽐较元素的个数
if (a[j] > a[j + 1]) {
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
}
}
五、性能分析:
若记录序列的初始状态为"正序",则冒泡排序过程只需进⾏⼀趟排序,在排序过程中只需进⾏n-1次⽐较,且不移动记录;反之,若记录序列的初始状态为"逆序",则需进⾏n(n-1)/2次⽐较和记录移动。
因此冒泡排序总的时间复杂度为O(n*n)。
六、算法优化:
冒泡排序法存在的不⾜及改进⽅法:
第⼀,在排序过程中,执⾏完最后的排序后,虽然数据已全部排序完备,但程序⽆法判断是否完成排序,为了解决这⼀不⾜,可设置⼀个标志位flag,将其初始值设置为⾮0,表⽰被排序的表是⼀个⽆序的表,每⼀次排序开始前设置flag值为0,在进⾏数据交换时,修改flag为⾮0。
在新⼀轮排序开始时,检查此标志,若此标志为0,表⽰上⼀次没有做过交换数据,则结束排序;否则进⾏排序;
/*
* 冒泡排序函数改进版
*/
public static void BubbleSort(int[] a) {
boolean flag = true;
while (flag) {
flag = false;
for (int i = 0; i < a.length - 1; i++) {
for (int j = 0; j < a.length - i ; j++) {
if (a[j] > a[j + 1]) {
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
flag = true;
}
}
if (!flag)
break; // 如果没有发⽣交换,则退出循环
}
}
}
}
第⼆、在冒泡排序中,⼀趟扫描有可能⽆数据交换,也有可能有⼀次或多次数据交换,在传统的冒泡排序算法及近年来的⼀些改进的算法中,只记录⼀趟扫描有⽆数据交换的信息,对数据交换发⽣的位置信息则不予处理。
为了充分利⽤这⼀信息,可以在⼀趟全局扫描中,对每⼀反序数据对进⾏局部冒泡排序处理,称之为局部冒泡排序。
局部冒泡排序与冒泡排序算法具有相同的时间复杂度,并且在正序和逆序的情况下,所需的关键字的⽐较次数和移动次数完全相同。
由于局部冒泡排序和冒泡排序的数据移动次数总是相同的,⽽局部冒泡排序所需关键字的⽐较次数常少于冒泡排序,这意味着局部冒泡排序很可能在平均⽐较次数上对冒泡排序有所改进,当⽐较次数较少的优点不⾜以抵消其程序复杂度所带来的额外开销,⽽当数据量较⼤时,局部冒泡排序的时间性能则明显优于冒泡排序。
对于N个⽆序数据,我们在进⾏⼀趟冒泡排序时,如果第k个数据和第k+1个数据逆序,那么对第k+1个数据进⾏⼀趟向前的冒泡排序,使其移动到合适的位置,也就是说让前⾯k+1个数据调节为正序。
因为这种冒泡法只对前k+1个数据冒泡处理,所以我们称它为——局部冒泡。