Java常见排序算法之Shell排序
??? 在學(xué)習(xí)算法的過程中,我們難免會(huì)接觸很多和排序相關(guān)的算法。總而言之,對(duì)于任何編程人員來說,基本的排序算法是必須要掌握的。
從今天開始,我們將要進(jìn)行基本的排序算法的講解。Are you ready?Let‘s go~~~
1、排序算法的基本概念的講解
???? 時(shí)間復(fù)雜度:需要排序的的關(guān)鍵字的比較次數(shù)和相應(yīng)的移動(dòng)的次數(shù)。
???? 空間復(fù)雜度:分析需要多少輔助的內(nèi)存。
???? 穩(wěn)定性:如果記錄兩個(gè)關(guān)鍵字的A和B它們的值相等,經(jīng)過排序后它們相對(duì)的位置沒有發(fā)生交換,那么我們稱這個(gè)排序算法是穩(wěn)定的。
????????????? 否則我們稱這個(gè)排序算法是不穩(wěn)定的。
???
??? 排序算法的常見分類:
??? 1、內(nèi)部排序(最常見的一種排序方式,不需要借助第三方輔助存儲(chǔ)工具)
??? 2、外部排序(需要借助外部存儲(chǔ)來輔助完成相關(guān)的排序操作)
??????? 如果參與排序的數(shù)據(jù)元素非常的多,數(shù)據(jù)量非常的大,計(jì)算機(jī)無法把整個(gè)排序過程放到內(nèi)存中進(jìn)行的話,
??????? 我們必須借助外部存儲(chǔ)器如磁盤來完成,這種排序方式,我們稱之為外部排序。
??????? 其中外部排序最常見的就是多路歸并排序,即將原始文件分解成多個(gè)能夠一次性裝入內(nèi)存的部分,分別把每一部分調(diào)入
??????? 內(nèi)存完成相應(yīng)的排序,接下來在對(duì)多個(gè)有序的外部文件進(jìn)行多路歸并排序。
??
?? 對(duì)于我們絕大多數(shù)的程序員而言,我們經(jīng)常遇到的為內(nèi)部排序。接下來我們將要對(duì)常見的內(nèi)部排序進(jìn)行相應(yīng)的講解。
??? 今天要講解的內(nèi)部排序?yàn)?
?? Shell排序
? 1.Shell排序的基本概念的講解
?? 希爾排序(Shell Sort)是插入排序的一種。也稱縮小增量排序,是直接插入排序算法的一種更高效的改進(jìn)版本。希爾排 ?? 序是非穩(wěn)定排序算法。該方法因DL.Shell于1959年提出而得名。 ?? 希爾排序是把記錄按下標(biāo)的一定增量分組,對(duì)每組使用直接插入排序算法排序;隨著增量逐漸減少,每組包含的關(guān)鍵詞 ?? 越來越多,當(dāng)增量減至1時(shí),整個(gè)文件恰被分成一組,算法便終止。 先取一個(gè)小于n的整數(shù)d1作為第一個(gè)增量,把文件的全部記錄分組。所有距離為d1的倍數(shù)的記錄放在同一個(gè)組中。先在各組內(nèi)進(jìn)行直接插 入排序;然后,取第二個(gè)增量d2<d1重復(fù)上述的分組和排序,直至所取的增量 =1( < …<d2<d1),即所有記錄放在同一組中進(jìn)行 直接插入排序?yàn)橹埂?? 該方法實(shí)質(zhì)上是一種分組插入方法 ? 比較相隔較遠(yuǎn)距離(稱為增量)的數(shù),使得數(shù)移動(dòng)時(shí)能跨過多個(gè)元素,則進(jìn)行一次比[2] 較就可能消除多個(gè)元素交換。 ? D.L.shell于1959年在以他名字命名的排序算法中實(shí)現(xiàn)了這一思想。算法先將要排序的一組數(shù)按某個(gè)增量d分成若干組, ? 每組中記錄的下標(biāo)相差d.對(duì)每組中全部元素進(jìn)行排序,然后再用一個(gè)較小的增量對(duì)它進(jìn)行,在每組中再進(jìn)行排序。當(dāng)增量 ? 減到1時(shí),整個(gè)要排序的數(shù)被分成一組,排序完成。 ? 一般的初次取序列的一半為增量,以后每次減半,直到增量為1。 ? 給定實(shí)例的shell排序的排序過程 ? 假設(shè)待排序文件有10個(gè)記錄,其關(guān)鍵字分別是: ? 49,38,65,97,76,13,27,49,55,04。 ? 增量序列的取值依次為: ? 5,2,1?
? 2.Shell排序的Java代碼實(shí)現(xiàn)
????
package com.yonyou.test;/*** 內(nèi)部排序算法之Shell排序* 默認(rèn)按照從小到大進(jìn)行排序操作* @author 小浩* @創(chuàng)建日期 2015-3-27*/ public class Test{public static void main(String[] args) {//需要進(jìn)行排序的數(shù)組int[] array=new int[]{8,3,2,1,7,4,6,5};//輸出原數(shù)組的內(nèi)容printResult(array);//shell排序操作shellSort(array);//輸出排序后的相關(guān)結(jié)果printResult(array);}/*** shell排序算法* 增量h=(h*3)+1; 這個(gè)增量公式是由Knuth給出的* 如果不是很了解的話請(qǐng)百度一下吧* @param array*/private static void shellSort(int[] array) {//首先根據(jù)數(shù)組的長(zhǎng)度確定增量的最大值int h=1;// 按h * 3 + 1得到增量序列的最大值while(h <= array.length / 3){h = h * 3 + 1;}//進(jìn)行增量查找和排序while(h>0){ for(int i=h;i<array.length;i++){for(int k=i;k<array.length;k+=h){//判斷是否需要重新排序,如果小于k-h處的值,需要重新排序if(array[k]<array[k-h]){int tempValue=array[k];int j=k;for(;j>=i&&tempValue<array[j-h];j-=h){array[j]=array[j-h];}array[j]=tempValue;}}printResult(array);}h=(h-1)/3;} }/*** * 輸出相應(yīng)數(shù)組的結(jié)果* @param array*/private static void printResult(int[] array) {for(int value:array) System.out.print(" "+value+" ");System.out.println();}/*** 交換數(shù)組中兩個(gè)變量的值* @param array* @param i* @param j*/private static void swap(int[] array,int i,int j){int temp=array[i];array[i]=array[j];array[j]=temp;} }?
?
?? ??
?
?
?
總結(jié)
以上是生活随笔為你收集整理的Java常见排序算法之Shell排序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: leetcode75
- 下一篇: Java基础小记