冒泡排序C,java,js實現及其三種優化方法

冒泡排序(Bubble Sort)是基本的交換排序算法之一

  • 定義:通過相鄰之間的元素比較大小,進行交換。

  • 基本思想:若前一個比後一個大,則交換,第一趟會把最大的放到最後。

  • 時間複雜度:O(n^2)

  • 穩定性:穩定(若元素相同,穩定即表示通過排序之後獲得的數組中,相同元素的位置不會發生改變)

1. 實現(下面分別用C語言,Java,和JavaScript 實現)
(1)C語言
#include<stdio.h>
int main()
{
	int i,j;
    int a[10] = {34,65,2,43,54,64,23,49,78,89};
    for(i=0;i<10-1;i++){
        for(j = 0;j<10-i-1;j++){
            if(a[j]>a[j+1]){
                int temp = a[j];
                a[j] = a[j+1];
                a[j+1] = temp;
            }
        }
    }
    for(i=0;i<10;i++)
    {
    	printf("%5d",a[i]);
    }
    printf("\n");
	return 0;
} 

運行結果如下在這裏插入圖片描述

(2)Java
public class Bubble_Sort {
	public static void main(String[] args){
		int i,j;
	    int [] a = {34,65,2,43,54,64,23,49,78,89};
	    for(i=0;i<10-1;i++){
	        for(j = 0;j<10-i-1;j++){
	            if(a[j]>a[j+1]){
	                int temp = a[j];
	                a[j] = a[j+1];
	                a[j+1] = temp;
	            }
	        }
	    }
	    for(i=0;i<10;i++)
	    {
	    	System.out.print(a[i]+"  ");
	    }
	}
}

運行結果如下
在這裏插入圖片描述

(3)JavaScript
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>
    var i,j;
    var a = [34,65,2,43,54,64,23,49,78,89];
    for(i=0;i<a.length-1;i++){
        for(j = 0;j<a.length-i-1;j++){
            if(a[j]>a[j+1]){
                var temp = a[j];
                a[j] = a[j+1];
                a[j+1] = temp;
            }
        }
    }
   console.log(a);
    </script>
</body>
</html>

運行結果如下:
在這裏插入圖片描述

2. 優化(3種優化,JavaScript實現)
(1)設置標誌位(適用於連片有序,但整體無序數據)

在排序過程中,如果有一趟沒有進行交換,則表示已完成排序,即不必繼續比較後面的元素,所以我們在交換處設置flag標誌位,若flag值沒有發生變化,則說明排序完成,跳出循環。

上面的js代碼若每一趟輸出數組a,則結果如下:
進行了9次排序。
在這裏插入圖片描述
優化代碼如下(js)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>
    var i,j,flag = 0;
    var a = [34,65,2,43,54,64,23,49,78,89];
    for(i=0;i<a.length-1;i++){
        flag = 0;
        for(j = 0;j<a.length-i-1;j++){
            if(a[j]>a[j+1]){
                flag = 1;
                var temp = a[j];
                a[j] = a[j+1];
                a[j+1] = temp;
            }
        }
        if(flag == 0){//表示這一趟沒有進行交換,即排序完成
            break;
        }
        console.log(a);
    }
    </script>
</body>
</html>

優化之後進行了5次排序,運行結果如下:
在這裏插入圖片描述

(2)每次交換記錄最後一次的位置(適用於前面無序,但是後面有序)

記錄每趟交換的最後位置作爲下趟比較的結束位置,到0時停止。因爲沒有交換,說明後面的數據已經有序,所以不做無效比較,下次直接比較到上次交換的最後位置即可。

一般的冒泡排序比較次數都是逐次少1,如圖:
數字爲每趟的比較次數,數組a爲每次的排序結果
在這裏插入圖片描述

但是優化會減少它的比較次數(代碼及結果如下)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>
    var i,j,end,t,c = 0;
    var a = [34,65,2,43,54,64,23,49,78,89];
    end = a.length-1;
    for(i=0;i<a.length-1;i++){
        t = 0;
        c = 0;//記錄比較次數,看是否優化
        for(j = 0;j<end;j++){
            c++;
            if(a[j]>a[j+1]){
                t = j;//記錄比較的位置
                var temp = a[j];
                a[j] = a[j+1];
                a[j+1] = temp;
            }
        }
        console.log(c);
        end = t;//把比較的最後位置作爲下次比較的結束位置
        console.log(a);
        if(t == 0){
            break;
        }
    }
    </script>
</body>
</html>

在這裏插入圖片描述

(3)雙向冒泡排序

每次既從左往右找最大值,又從右往左找最小值,把最大值放最後,最小值放前面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>
    var a = [34,65,2,43,54,64,23,49,78,89];
    var i,j,end,t,c = 0,flag;
    var left = 0;//左邊界的初始值
    var right = a.length-1;//右邊界的初始值
    var before = 0,after = 0;//記錄左右邊界的最後一次位置
    for(i=0;i<a.length-1;i++){
        flag = 0;c = 0;
        //正向尋找最大值
        for(j = left;j<right;j++){
            if(a[j]>a[j+1]){
                c++;
                after = j;//記錄比較的位置
                var temp = a[j];
                a[j] = a[j+1];
                a[j+1] = temp;
                flag = 1;
            }
        }
        //反向尋找最小值
        for(j = right;j>left;j--){
            if(a[j]<a[j+1]){
                c++;
                before = j;//記錄比較的位置
                var temp = a[j];
                a[j] = a[j+1];
                a[j+1] = temp;
                flag = 1;
            }
        }
        if(flag == 0){
            break;
        }
        left = before;
        right = after;
        console.log(c);
        console.log(a);
    }
    </script>
</body>
</html>

運行結果如下:(數字表示比較次數,數組爲每趟比較結果)
在這裏插入圖片描述

最後說一下穩定性。

一般來說,冒泡排序是穩定的,但是一個排序的穩定性主要還是由具體算法決定,不穩定的算法在某種條件下可以變爲穩定的算法,而穩定的算法在某種條件下也可以變爲不穩定的算法。比如今天所分享的冒泡排序,將元素交換的條件改成a[j]>=a[j+1],則兩個相等的元素就會交換位置,即不穩定。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章