冒泡排序
應該是最簡單的排序算法了
描述:
在要排序的一組數中,對當前還未排好序的範圍內的全部數,自上而下對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較小的往上冒。即:每當兩相鄰的數比較後發現它們的排序與排序要求相反時,就將它們互換。如下圖所示
算法(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]+" ");
}
}
}