這篇文章主要介紹“Java排序算法實(shí)現(xiàn)的方法是什么”,在日常操作中,相信很多人在Java排序算法實(shí)現(xiàn)的方法是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對(duì)大家解答”Java排序算法實(shí)現(xiàn)的方法是什么”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!
創(chuàng)新互聯(lián)公司總部坐落于成都市區(qū),致力網(wǎng)站建設(shè)服務(wù)有成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)、網(wǎng)絡(luò)營銷策劃、網(wǎng)頁設(shè)計(jì)、網(wǎng)站維護(hù)、公眾號(hào)搭建、小程序開發(fā)、軟件開發(fā)等為企業(yè)提供一整套的信息化建設(shè)解決方案。創(chuàng)造真正意義上的網(wǎng)站建設(shè),為互聯(lián)網(wǎng)品牌在互動(dòng)行銷領(lǐng)域創(chuàng)造價(jià)值而不懈努力!
冒泡排序:
(1)原理:
從第一個(gè)數(shù)據(jù)開始,與第二個(gè)數(shù)據(jù)相比較,如果第二個(gè)數(shù)據(jù)小于第一個(gè)數(shù)據(jù),則交換兩個(gè)數(shù)據(jù)的位置。
指針由第一個(gè)數(shù)據(jù)移向第二個(gè)數(shù)據(jù),第二個(gè)數(shù)據(jù)與第三個(gè)數(shù)據(jù)相比較,如果第三個(gè)數(shù)據(jù)小于第二個(gè)數(shù)據(jù),則交換兩個(gè)數(shù)據(jù)的位置。
依此類推,完成第一輪排序。第一輪排序結(jié)束后,最大的元素被移到了最右面。
依照上面的過程進(jìn)行第二輪排序,將第二大的排在倒數(shù)第二的位置。
重復(fù)上述過程,沒排完一輪,比較次數(shù)就減少一次。
(2)例子:
待排序數(shù)據(jù):7, 6, 9, 8, 5,1
第一輪排序過程:
指針先指向7,7和6比較,6<7,交換6和7的位置,結(jié)果為:6,7,9,8,5,1 指針指向第二個(gè)元素7,7和9比較,9>7,不用交換位置,結(jié)果仍為:6,7,9,8,5,1 指針指向第三個(gè)元素9,比較9和8,8<9,交換8和9的位置,結(jié)果為:6,7,8,9,5,1 指針指向第四個(gè)元素9,比較9和5,5<9,交換5和9,結(jié)果為:6,7,8,5,9,1 指針指向第五個(gè)元素9,比較9和1,1<9,交換1和9的位置,結(jié)果為6,7,8,5,1,9
第一輪排序結(jié)束后,最大的數(shù)字9被移到了最右邊。
進(jìn)行第二輪排序,過程同上,只是由于最大的9已經(jīng)放在最右邊了,因此不用在比較9了,少了一次比較,第二輪結(jié)束的結(jié)果為:6,7,5,1,8,9
第三輪結(jié)果:6,5,1,7,8,9
第四輪比較結(jié)果:5,1,6,7,8,9
第五輪比較結(jié)果:1,5,6,7,8,9
最終排序結(jié)果為:1,5,6,7,8,9,由上可知N個(gè)數(shù)據(jù)排序,需要進(jìn)行N-1輪排序;第i輪排序需要的比較次數(shù)為N-i次。
(3)編碼思路:
需要兩層循環(huán),第一層循環(huán)i表示排序的輪數(shù),第二層循環(huán)j表示比較的次數(shù)。
(4)代碼實(shí)現(xiàn):
實(shí)例
package com.test.insertsort;/** * 選擇排序 * @author Administrator * */public class ChooseSort { private int[] array; private int length; public ChooseSort(int[] array){ this.array = array; this.length = array.length; } /** * 打印數(shù)組中的所有元素 */ public void display(){ for(int i: array){ System.out.print(i+" "); } System.out.println(); } /** * 選擇排序算法 */ public void chooseSort(){ for(int i=0; i<length-1; i++){ int minIndex = i; for(int j=minIndex+1;j<length;j++){ if(array[j]<array[minIndex]){ minIndex = j; } } int temp = array[i]; array[i] = array[minIndex]; array[minIndex] = temp; } } public static void main(String[] args){ int[] array={100,45,36,21,17,13,7}; ChooseSort cs = new ChooseSort(array); System.out.println("排序前的數(shù)據(jù)為:"); cs.display(); cs.chooseSort(); System.out.println("排序后的數(shù)據(jù)為:"); cs.display(); }}
(5)選擇排序總結(jié):
N個(gè)元素需要排序N-1輪;
第i輪需要比較N-i次;
N個(gè)元素排序,需要比較n(n-1)/2次;
選擇排序的算法復(fù)雜度仍為O(n*n);
相比于冒泡排序,選擇排序的交換次數(shù)大大減少,因此速度要快于冒泡排序
插入排序
插入排序是簡單排序中最快的排序算法,雖然時(shí)間復(fù)雜度仍然為O(n*n),但是卻比冒泡排序和選擇排序快很多。
(1)原理:
將指針指向某個(gè)元素,假設(shè)該元素左側(cè)的元素全部有序,將該元素抽取出來,然后按照從右往左的順序分別與其左邊的元素比較,遇到比其大的元素便將元素右移,直到找到比該元素小的元素或者找到最左面發(fā)現(xiàn)其左側(cè)的元素都比它大,停止;
此時(shí)會(huì)出現(xiàn)一個(gè)空位,將該元素放入到空位中,此時(shí)該元素左側(cè)的元素都比它小,右側(cè)的元素都比它大;
指針向后移動(dòng)一位,重復(fù)上述過程。每操作一輪,左側(cè)有序元素都增加一個(gè),右側(cè)無序元素都減少一個(gè)。
(2)例子:
待比較數(shù)據(jù):7, 6, 9, 8, 5,1
第一輪:指針指向第二個(gè)元素6,假設(shè)6左面的元素為有序的,將6抽離出來,形成7,_,9,8,5,1,從7開始,6和7比較,發(fā)現(xiàn)7>6。將7右移,形成_,7,9,8,5,1,6插入到7前面的空位,結(jié)果:6,7,9,8,5,1
第二輪:指針指向第三個(gè)元素9,此時(shí)其左面的元素6,7為有序的,將9抽離出來,形成6,7,_,8,5,1,從7開始,依次與9比較,發(fā)現(xiàn)9左側(cè)的元素都比9小,于是無需移動(dòng),把9放到空位中,結(jié)果仍為:6,7,9,8,5,1
第三輪:指針指向第四個(gè)元素8,此時(shí)其左面的元素6,7,9為有序的,將8抽離出來,形成6,7,9,_,5,1,從9開始,依次與8比較,發(fā)現(xiàn)8<9,將9向后移,形成6,7,_,9,5,1,8插入到空位中,結(jié)果為:6,7,8,9,5,1
第四輪:指針指向第五個(gè)元素5,此時(shí)其左面的元素6,7,8,9為有序的,將5抽離出來,形成6,7,8,9,_,1,從9開始依次與5比較,發(fā)現(xiàn)5比其左側(cè)所有元素都小,5左側(cè)元素全部向右移動(dòng),形成_,6,7,8,9,1,將5放入空位,結(jié)果5,6,7,8,9,1。
第五輪:同上,1被移到最左面,最后結(jié)果:1,5,6,7,8,9。
(3)編碼分析:
需要兩層循環(huán),第一層循環(huán)index表示上述例子中的指針,即遍歷從坐標(biāo)為1開始的每一個(gè)元素;第二層循環(huán)從leftindex=index-1開始,leftindex--向左遍歷,將每一個(gè)元素與i處的元素比較,直到j(luò)處的元素小于i出的元素或者leftindex<0;遍歷從i到j(luò)的每一個(gè)元素使其右移,最后將index處的元素放到leftindex處的空位處。
(4)代碼實(shí)現(xiàn):
實(shí)例
package com.test.insertsort;/** * 插入排序算法: * 1、以數(shù)組的某一位作為分隔位,比如index=1,假設(shè)左面的都是有序的. * * 2、將index位的數(shù)據(jù)拿出來,放到臨時(shí)變量里,這時(shí)index位置就空出來了. * * 3、從leftindex=index-1開始將左面的數(shù)據(jù)與當(dāng)前index位的數(shù)據(jù)(即temp)進(jìn)行比較,如果array[leftindex]>temp, * 則將array[leftindex]后移一位,即array[leftindex+1]=array[leftindex],此時(shí)leftindex就空出來了. * * 4、再用index-2(即leftindex=leftindex-1)位的數(shù)據(jù)和temp比,重復(fù)步驟3, * 直到找到<=temp的數(shù)據(jù)或者比到了最左面(說明temp最?。V贡容^,將temp放在當(dāng)前空的位置上. * * 5、index向后挪1,即index=index+1,temp=array[index],重復(fù)步驟2-4,直到index=array.length,排序結(jié)束, * 此時(shí)數(shù)組中的數(shù)據(jù)即為從小到大的順序. * * @author bjh * */public class InsertSort { private int[] array; private int length; public InsertSort(int[] array){ this.array = array; this.length = array.length; } public void display(){ for(int a: array){ System.out.print(a+" "); } System.out.println(); } /** * 插入排序方法 */ public void doInsertSort(){ for(int index = 1; index<length; index++){//外層向右的index,即作為比較對(duì)象的數(shù)據(jù)的index int temp = array[index];//用作比較的數(shù)據(jù) int leftindex = index-1; while(leftindex>=0 && array[leftindex]>temp){//當(dāng)比到最左邊或者遇到比temp小的數(shù)據(jù)時(shí),結(jié)束循環(huán) array[leftindex+1] = array[leftindex]; leftindex--; } array[leftindex+1] = temp;//把temp放到空位上 } } public static void main(String[] args){ int[] array = {38,65,97,76,13,27,49}; InsertSort is = new InsertSort(array); System.out.println("排序前的數(shù)據(jù)為:"); is.display(); is.doInsertSort(); System.out.println("排序后的數(shù)據(jù)為:"); is.display(); }}
(5)插入排序分析:
時(shí)間復(fù)雜度,由于仍然需要兩層循環(huán),插入排序的時(shí)間復(fù)雜度仍然為O(n*n)。
比較次數(shù):在第一輪排序中,插入排序最多比較一次;在第二輪排序中插入排序最多比較二次;以此類推,最后一輪排序時(shí),最多比較N-1次,因此插入排序的最多比較次數(shù)為1+2+...+N-1=N*(N-1)/2。盡管如此,實(shí)際上插入排序很少會(huì)真的比較這么多次,因?yàn)橐坏┌l(fā)現(xiàn)左側(cè)有比目標(biāo)元素小的元素,比較就停止了,因此,插入排序平均比較次數(shù)為N*(N-1)/4。
移動(dòng)次數(shù):插入排序的移動(dòng)次數(shù)與比較次數(shù)幾乎一致,但移動(dòng)的速度要比交換的速度快得多。
綜上,插入排序的速度約比冒泡排序快一倍(比較次數(shù)少一倍),比選擇排序還要快一些,對(duì)于基本有序的數(shù)據(jù),插入排序的速度會(huì)很快,是簡單排序中效率最高的排序算法。
快排、冒泡排序、選擇排序、插入排序、歸并排序
一、概述:
上文介紹了常見簡單算法:冒泡排序、選擇排序和插入排序。本文介紹高級(jí)排序算法:快速排序和歸并排序。在開始介紹算法之前,首先介紹高級(jí)算法所需要的基礎(chǔ)知識(shí):劃分、遞歸,并順帶介紹二分查找算法。
二、劃分:
劃分是快速排序的前提,即把數(shù)據(jù)分為兩組,大于特定值的數(shù)據(jù)在一組,小于特定值的數(shù)據(jù)在另一組??焖倥判蚣词怯蓜澐趾瓦f歸操作來完成的。
(1)原理:
定義一個(gè)閾值,分別從最左面和最右面向中間遍歷元素,左面找到一個(gè)大于閾值的數(shù)據(jù)便停止,右邊找到一個(gè)小于閾值的數(shù)據(jù)便停止,如果此時(shí)左右兩邊都還沒有走到中間,則交換左面大于閾值的數(shù)據(jù)和右面小于閾值的數(shù)據(jù);重復(fù)上述過程,直到左面指針和右面指針相遇,此時(shí)左面數(shù)據(jù)均小于閾值,右面數(shù)據(jù)均大于閾值,劃分結(jié)束。劃分結(jié)束后,數(shù)據(jù)仍然是無序的,但更接近于有序。
(2)例子:
待劃分?jǐn)?shù)據(jù):7, 6, 9, 8, 5,1,假設(shè)閾值為5
第一輪:左指針指向7,右指針指向1,左指針向后移,右指針向左移,發(fā)現(xiàn)左面第一個(gè)大于5的元素7,右面第一個(gè)小于5的元素1,交換7和1的位置,結(jié)果:1,6,9,8,5,7;
第二輪:從6開始找大于5的數(shù)字,找到6,右邊從5起找小于5的數(shù)字,找到1,但此時(shí)由于6在1的右面,,即右指針<左指針,左右指針交叉,此時(shí)劃分結(jié)束。原數(shù)列被劃分為兩部分,左側(cè)子數(shù)列只有一個(gè)元素,即為1,其為小于閾值的子數(shù)列;右側(cè)子數(shù)列包括5個(gè)元素,均為大于閾值5的元素。 (3)代碼實(shí)現(xiàn):
實(shí)例
package com.test.insertsort; /** * 劃分、遞歸、快排 * @author bjh * */public class QuickSort { /**待排序、劃分?jǐn)?shù)組*/ private int[] array; /**數(shù)組長度*/ private int length; public QuickSort(int[] array){ this.array = array; this.length = array.length; } /** * 打印元素 */ public void printArray(){ for(int i=0; i<length; i++){ System.out.print(array[i]+" "); } System.out.println(); } /** * 劃分 * @return 劃分的分界點(diǎn) */ public int partition(int left, int right, int pivot){ //左指針的起點(diǎn),left-1是由于在后面的循環(huán)中,每循環(huán)一次左指針都要右移, //這樣可以確保左指針從左邊第一個(gè)元素開始,不然是從第二個(gè)開始 int leftpoint = left-1; //右指針的起點(diǎn),right+1是由于后面的循環(huán)中,每循環(huán)一次右指針都要左移, //這樣可以確保右指針從最右邊開始,不然是從倒數(shù)第二個(gè)開始 int rightpoint = right+1; while(true){ //找到左邊大于pivot的數(shù)據(jù),或者走到了最右邊仍然沒有找到比pivot大的數(shù)據(jù) while(leftpoint<right && array[++leftpoint]<pivot); //找到右邊小于pivot的數(shù)據(jù),或者走到了最左邊仍然沒有找到比pivot小的數(shù)據(jù) while(rightpoint>left && array[--rightpoint]>pivot); //左指針和右指針重疊或相交 if(leftpoint >= rightpoint){ break; }else{ //交換左邊大的和右邊小的數(shù)據(jù) swap(leftpoint,rightpoint); } } //返回分界點(diǎn),即右邊子數(shù)組中最左邊的點(diǎn) return leftpoint; } /** * 交換數(shù)據(jù) */ public void swap(int leftpoint,int rightpoint){ int temp = array[leftpoint]; array[leftpoint] = array[rightpoint]; array[rightpoint] = temp; } public static void main(String args[]){ int[] array = {99,78,26,17,82,36,9,81,22,100,30,20,17,85}; QuickSort qs = new QuickSort(array); System.out.println("劃分前的數(shù)據(jù)為:"); qs.printArray(); int bound = qs.partition(0, array.length-1, 50); System.out.println("劃分后的數(shù)據(jù)為:"); qs.printArray(); System.out.println("劃分的分界點(diǎn)為:" + array[bound] + ",分界點(diǎn)的坐標(biāo)為:" + bound); } }
運(yùn)行結(jié)果為:
到此,關(guān)于“Java排序算法實(shí)現(xiàn)的方法是什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!
當(dāng)前文章:Java排序算法實(shí)現(xiàn)的方法是什么
網(wǎng)頁網(wǎng)址:http://jinyejixie.com/article18/gceidp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、品牌網(wǎng)站制作、網(wǎng)頁設(shè)計(jì)公司、網(wǎng)站排名、關(guān)鍵詞優(yōu)化、ChatGPT
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)