冒泡排序
应该是最简单的排序算法了
描述:
在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。如下图所示
算法(java):
public static void bubbleSort(int a[]) {
int exchangeCount = 0;
for (int i = 0; i < a.length - 1; i++) {
for (int j = 0; j < a.length - i - 1; j++) {
exchangeCount++;
if (a[j] > a[j + 1]) {
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
System.out.println(" 普通冒泡排序 比较次数 " + exchangeCount);
for (int i = 0; i <a.length ; i++) {
System.out.print(a[i]+" ");
}
System.out.println();
}
改进
对冒泡排序常见的改进方法是加入一标志性变量exchange,用于标志某一趟排序过程中是否有数据交换,如果进行某一趟排序时并没有进行数据交换,则说明数据已经按要求排列好,可立即结束排序,避免不必要的比较过程。本文再提供以下两种改进算法:
1.设置一标志性变量pos,用于记录每趟排序中最后一次进行交换的位置。由于pos位置之后的记录均已交换到位,故在进行下一趟排序时只要扫描到pos位置即可。
改进后算法如下:
public static void bubbleSort_1(int a[]) {
int exchangeCount = 0;
int i = a.length - 1;//初始时候,最终交换位置不变
while (i > 0) {
int pos = 0;//标志变量,每一趟开始都是0
for (int j = 0; j < i; j++) {
exchangeCount++;
if (a[j] > a[j + 1]) {
pos = j;//如果在一躺排序过程中有交换,就记录pos位置
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
i = pos;//最终当pos位置不为0的时候,继续吓一躺排序。。当pos位置为0 表示在这一趟过程没有发生交换,元素都是有序的,自然退出循环
}
System.out.println(" 加标志变量pos比较次数 " + exchangeCount);
for (i = 0; i <a.length ; i++) {
System.out.print(a[i]+" ");
}
System.out.println();
}
2.传统冒泡排序中每一趟排序操作只能找到一个最大值或最小值,我们考虑利用在每趟排序中进行正向和反向两遍冒泡的方法一次可以得到两个最终值(最大者和最小者) , 从而使排序趟数几乎减少了一半。
改进后的算法实现为:
public static void bubbleSort_2(int a[]) {
int exchangeCount = 0;
int low =0;
int high=a.length-1;//设置变量初始值
int temp,j;
while (low<high){//当最低位依然小于最高位的时候,才会循环
for (j=low;j<high;j++){
//正向冒泡,找出最大值
exchangeCount++;
if (a[j]>a[j+1]){
temp = a[j];
a[j]=a[j+1];
a[j+1] = temp;
}
}
high--;//最大值找到了,修改high的位置
//反向冒泡找出最小值,
for (j=high;j>low;j--){
exchangeCount++;
if (a[j]<a[j-1]){
temp = a[j];
a[j]=a[j-1];
a[j-1] = temp;
}
}
low++;//最小值找到了,修改low的位置,
}
System.out.println(" 正向逆向两边冒泡比较次数 " + exchangeCount);
for (int i = 0; i <a.length ; i++) {
System.out.print(a[i]+" ");
}
}
完整的算法程序:
package com.zq.algorithm.sort;
/**
* Created by zhengshouzi on 2015/10/31.
*/
public class BubbleSort {
public static void main(String[] args) {
int[] a = {49, 38, 65, 97, 76, 13, 27, 49};
int[] b = {49, 38, 65, 97, 76, 13, 27, 49};
int[] c = {49, 38, 65, 97, 76, 13, 27, 49};
bubbleSort(a);
bubbleSort_1(b);
bubbleSort_2(c);
}
public static void bubbleSort(int a[]) {
int exchangeCount = 0;
for (int i = 0; i < a.length - 1; i++) {
for (int j = 0; j < a.length - i - 1; j++) {
exchangeCount++;
if (a[j] > a[j + 1]) {
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
System.out.println(" 普通冒泡排序 比较次数 " + exchangeCount);
for (int i = 0; i <a.length ; i++) {
System.out.print(a[i]+" ");
}
System.out.println();
}
public static void bubbleSort_1(int a[]) {
int exchangeCount = 0;
int i = a.length - 1;//初始时候,最终交换位置不变
while (i > 0) {
int pos = 0;//标志变量,每一趟开始都是0
for (int j = 0; j < i; j++) {
exchangeCount++;
if (a[j] > a[j + 1]) {
pos = j;//如果在一躺排序过程中有交换,就记录pos位置
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
i = pos;//最终当pos位置不为0的时候,继续吓一躺排序。。当pos位置为0 表示在这一趟过程没有发生交换,元素都是有序的,自然退出循环
}
System.out.println(" 加标志变量pos比较次数 " + exchangeCount);
for (i = 0; i <a.length ; i++) {
System.out.print(a[i]+" ");
}
System.out.println();
}
public static void bubbleSort_2(int a[]) {
int exchangeCount = 0;
int low =0;
int high=a.length-1;//设置变量初始值
int temp,j;
while (low<high){//当最低位依然小于最高位的时候,才会循环
for (j=low;j<high;j++){
//正向冒泡,找出最大值
exchangeCount++;
if (a[j]>a[j+1]){
temp = a[j];
a[j]=a[j+1];
a[j+1] = temp;
}
}
high--;//最大值找到了,修改high的位置
//反向冒泡找出最小值,
for (j=high;j>low;j--){
exchangeCount++;
if (a[j]<a[j-1]){
temp = a[j];
a[j]=a[j-1];
a[j-1] = temp;
}
}
low++;//最小值找到了,修改low的位置,
}
System.out.println(" 正向逆向两边冒泡比较次数 " + exchangeCount);
for (int i = 0; i <a.length ; i++) {
System.out.print(a[i]+" ");
}
}
}
所有的算法源代码都可以从我的在我的GitHub上面找到:https://github.com/ThinerZQ/AllAlgorithmInJava