日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

java 冒泡排序_Java冒泡排序详解

發(fā)布時(shí)間:2025/3/20 java 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 冒泡排序_Java冒泡排序详解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Java冒泡排序

排序算法概述

所謂排序,就是使一串記錄,按照其中的某個(gè)或某些關(guān)鍵字的大小,遞增或遞減的排列起來的操作。排序算法,就是如何使得記錄按照要求排列的方法。排序算法在很多領(lǐng)域得到相當(dāng)?shù)刂匾?#xff0c;尤其是在大量數(shù)據(jù)的處理方面。

穩(wěn)定性:一個(gè)排序算法是穩(wěn)定的,就是當(dāng)有兩個(gè)相等記錄的關(guān)鍵字R和S,且在原本的列表中R出現(xiàn)在S之前,在排序過的列表中R也將會(huì)是在S之前。

如果算法是穩(wěn)定的有什么好處呢?排序算法如果是穩(wěn)定的,那么從一個(gè)鍵上排序,然后再從另一個(gè)鍵上排序,第一個(gè)鍵排序的結(jié)果可以為第二個(gè)鍵排序所用。基數(shù)排序就是這樣,先按低位排序,逐次按高位排序,低位相同的元素其順序再高位也相同時(shí)是不會(huì)改變的。

排序算法根據(jù)是否需要訪問外存分為內(nèi)部排序和外部排序。

內(nèi)部排序是指待排序列完全存放在內(nèi)存中所進(jìn)行的排序過程,適合不太大的元素序列。

外部排序指的是大文件的排序,即待排序的記錄存儲在外存儲器上,待排序的文件無法一次裝入內(nèi)存,需要在內(nèi)存和外部存儲器之間進(jìn)行多次數(shù)據(jù)交換,以達(dá)到排序整個(gè)文件的目的。

我們現(xiàn)在要討論的排序都是內(nèi)部排序。

冒泡排序

冒泡排序的效率很低,但是算法實(shí)現(xiàn)起來很簡單,因此很適合作為研究排序的入門算法。

基本思想

對當(dāng)前還未排好序的范圍內(nèi)的全部數(shù),自上而下對相鄰的倆個(gè)數(shù)依次進(jìn)行比較和調(diào)整,讓較大的數(shù)下沉,較小的數(shù)往上冒。即:每當(dāng)倆相鄰的數(shù)比較后發(fā)現(xiàn)他們的排序與排序的要求相反時(shí),就將他們交換。每次遍歷都可確定一個(gè)最大值放到待排數(shù)組的末尾,下次遍歷,對該最大值以及它之后的元素不再排序(已經(jīng)排好)。

java實(shí)現(xiàn)

public class Sort{ private int [] array; public Sort(int [] array){ this.array = array; } //按順序打印數(shù)組中的元素 public void display(){ for(int i=0;iarray[j]){ //如果前一位大于后一位,交換位置 temp = array[j-1]; array[j-1] = array[j]; array[j] = temp; } } System.out.print("第"+(i+1)+"輪排序結(jié)果:"); display(); } } }

測試:

public static void main(String[] args) { int [] a = {1,5,4,11,2,20,18}; Sort sort = new Sort(a); System.out.print("未排序時(shí)的結(jié)果:"); sort.display(); sort.bubbleSort(); }

打印結(jié)果:

算法分析

上面的例子中,待排數(shù)組中一共有7個(gè)數(shù),第一輪排序時(shí)進(jìn)行了6次比較,第二輪排序時(shí)進(jìn)行了5比較,依次類推,最后一輪進(jìn)行了一次比較。加入元素總數(shù)為N,則一共需要的比較次數(shù)為:

(N-1)+ (N-2)+ (N-3)+ ...1=N*(N-1)/2

這樣,算法約做了N2/2次比較。因?yàn)橹挥性谇懊娴脑乇群竺娴脑卮髸r(shí)才交換數(shù)據(jù),所以交換的次數(shù)少于比較的次數(shù)。如果數(shù)據(jù)是隨機(jī)的,大概有一半數(shù)據(jù)需要交換,則交換的次數(shù)為N2/4(不過在最壞情況下,即初始數(shù)據(jù)逆序時(shí),每次比較都需要交換)。

交換和比較的操作次數(shù)都與N2成正比,由于在大O表示法中,常數(shù)忽略不計(jì),冒泡排序的時(shí)間復(fù)雜度為O(N2)。O(N2)的時(shí)間復(fù)雜度是一個(gè)比較糟糕的結(jié)果,尤其在數(shù)據(jù)量很大的情況下。所以冒泡排序通常不會(huì)用于實(shí)際應(yīng)用。

冒泡排序的改進(jìn)

上面已經(jīng)分析過,冒泡排序的效率比較低,所以我們要通過各種方法改進(jìn)。

最簡單的改進(jìn)方法是加入一標(biāo)志性變量exchange,用于標(biāo)志某一趟排序過程中是否有數(shù)據(jù)交換,如果進(jìn)行某一趟排序時(shí)并沒有進(jìn)行數(shù)據(jù)交換,則說明數(shù)據(jù)已經(jīng)按要求排列好,可立即結(jié)束排序,避免不必要的比較過程.

在上例中,第四輪排序之后實(shí)際上整個(gè)數(shù)組已經(jīng)是有序的了,最后兩輪的比較沒必要進(jìn)行。

改進(jìn)后的代碼如下:

//冒泡排序改進(jìn)1 public void bubbleSort_improvement_1(){ int temp; int len = array.length; for(int i=0;iarray[j]){ //如果前一位大于后一位,交換位置 temp = array[j-1]; array[j-1] = array[j]; array[j] = temp; if(!exchange) exchange =true; //發(fā)生了交換操作 } } System.out.print("第"+(i+1)+"輪排序結(jié)果:"); display(); if(!exchange) break; //如果上一輪沒有發(fā)生交換數(shù)據(jù),證明已經(jīng)是有序的了,結(jié)束排序 } }

用同樣的初始數(shù)組測試,打印結(jié)果如下:

上面的改進(jìn)方法,是根據(jù)上一輪排序有沒有發(fā)生數(shù)據(jù)交換作為標(biāo)識,進(jìn)一步思考,如果上一輪排序中,只有后一段的幾個(gè)元素沒有發(fā)生數(shù)據(jù)交換,是不是可以判定這一段不用在進(jìn)行比較了呢?答案是肯定的。

例如上面的例子中,前四輪的排序結(jié)果為:

未排序時(shí)的結(jié)果:1 5 4 11 2 20 18第1輪排序結(jié)果:1 4 5 2 11 18 20第2輪排序結(jié)果:1 4 2 5 11 18 20第3輪排序結(jié)果:1 2 4 5 11 18 20第4輪排序結(jié)果:1 2 4 5 11 18 20

第1輪排序之后,11、18、20已經(jīng)是有序的了,后面的幾次排序后它們的位置都沒有變化,但是根據(jù)冒泡算法,18依然會(huì)在第2輪參與比較,11依然會(huì)在第2輪、第3輪參與比較,其實(shí)都是無用功。

我們可以對算法進(jìn)一步改進(jìn):設(shè)置一個(gè)pos指針,pos后面的數(shù)據(jù)在上一輪排序中沒有發(fā)生交換,下一輪排序時(shí),就對pos之后的數(shù)據(jù)不再比較。

代碼改動(dòng)如下:

//冒泡排序改進(jìn)2 public void bubbleSort_improvement_2(){ int temp; int counter = 1; int endPoint = array.length-1; //endPoint代表最后一個(gè)需要比較的元素下標(biāo) while(endPoint>0){ intpos = 1; for(int j=1;j<=endPoint;j++){ if(array[j-1]>array[j]){ //如果前一位大于后一位,交換位置 temp= array[j-1]; array[j-1]= array[j]; array[j]= temp; pos= j; //下標(biāo)為j的元素與下標(biāo)為j-1的元素發(fā)生了數(shù)據(jù)交換 } } //下一輪排序時(shí)只對下標(biāo)小于pos的元素排序,下標(biāo)大于等于pos的元素已經(jīng)排好 endPoint= pos-1; System.out.print("第"+counter+"輪排序結(jié)果:"); display(); } }

對的算法來說,沒有最好,只有更好。上面的兩種改進(jìn)方法其實(shí)治標(biāo)不治本,是一種“揚(yáng)湯止沸”的改進(jìn),下面我們來一次“釜底抽薪”的改進(jìn)。

傳統(tǒng)的冒泡算法每次排序只確定了最大值,我們可以在每次循環(huán)之中進(jìn)行正反兩次冒泡,分別找到最大值和最小值,如此可使排序的輪數(shù)減少一半。

改進(jìn)代碼如下:

//冒泡排序改進(jìn)3 public void bubbleSort_improvement_3(){ int temp; int low = 0; int high = array.length-1; int counter = 1; while(lowarray[i+1]){ //如果前一位大于后一位,交換位置 temp= array[i]; array[i]= array[i+1]; array[i+1]= temp; } } --high; for(int j=high;j>low;--j){ //反向冒泡,確定最小值 if(array[j]

如果有興趣和我們一起討論問題的話,不妨加下我們?nèi)喊?,記得加群的時(shí)候?qū)懮衔颐?ID:BigMoreKT:984370849

總結(jié)

以上是生活随笔為你收集整理的java 冒泡排序_Java冒泡排序详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。