一個Java小白通向數(shù)據(jù)結(jié)構(gòu)算法之旅(7) - 簡單排序總結(jié)

前言

昨天雙11凉馆,什么也沒買。因為沒有想到什么必需的用品亡资,何況也沒有錢澜共。身為屌絲的我,只能敲敲代碼锥腻,寫一寫總結(jié)嗦董,豈不美滋滋哉。今天看了《五億探長雷洛》這部電影瘦黑,非常喜歡劉德華飾演的雷洛京革,因此雷洛照片鎮(zhèn)樓。

雷洛.jpg

幾種簡單排序的比較

  • 一般情況幾乎不太使用冒泡排序算法幸斥,它過于簡單了匹摇。當(dāng)數(shù)據(jù)量很小的時候,它會有些應(yīng)用價值甲葬。

  • 選擇排序雖然把交換次數(shù)降到了最低廊勃,但比較的次數(shù)仍然很大。當(dāng)數(shù)據(jù)量很小经窖,并且交換次數(shù)相當(dāng)于比較數(shù)據(jù)更加耗時的情況下坡垫,可以應(yīng)用選擇排序。

  • 但數(shù)據(jù)量比較小或基本上有序時画侣,插入排序算法是三種簡單排序算法中最好的選擇冰悠。


歸納

  • 這幾種簡單排序算法中都假定了數(shù)據(jù)作為數(shù)據(jù)存儲結(jié)構(gòu)。

  • 排序包括比較數(shù)組中數(shù)據(jù)項的關(guān)鍵字和移動相應(yīng)的數(shù)據(jù)項配乱,直到它們排好序為止溉卓。

  • 3種簡單排序算法復(fù)雜度都是 O(N^2) ,不過插入排序在某種情況下會比冒泡排序皮迟,選擇排序快的多。算法復(fù)雜度結(jié)果為10^8 的算法是秒級算法的诵。O(N^2)的算法万栅,在數(shù)據(jù)項小于10000時佑钾,運行才會是秒級西疤。

  • 不變性是指算法運行時保持不變的條件。冒泡排序的不變性是out右邊的所有數(shù)據(jù)項為有序休溶。選擇排序中不變性是下標小于或等于out的數(shù)據(jù)都是有序的代赁。插入排序中的不變性是下標比out小的數(shù)據(jù)項是局部有序的。這里out指的是循環(huán)中的變量兽掰。

  • 冒泡排序是效率最差的算法芭碍,但它是最簡單的。

  • 插入排序算法是O(N^2)排序算法中應(yīng)用最多的孽尽。

  • 如果具有相同關(guān)鍵字的數(shù)據(jù)項窖壕,經(jīng)過排序他們的順序保持不變,這樣的排序就是穩(wěn)定的杉女。

  • 這幾種排序中瞻讽,除了需要初始數(shù)組之外,還需要一個臨時變量熏挎。


對象排序

我們有時候需要比較對象中的關(guān)鍵字速勇,來給一組對象進行排序。

  • 先定義一個Person類坎拐。
public class Person {
    private String name;
    private Integer age;
    private Integer height;

    public Person(String name, Integer age, Integer height) {
        super();
        this.name = name;
        this.age = age;
        this.height = height;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getHeight() {
        return height;
    }

    public void setHeight(Integer height) {
        this.height = height;
    }

    public void displayPerson() {
        System.out.println("name:" + name + ", age:" + age + ", height:" + height);
    }
}
  • 再去定義一個ArrayInOb數(shù)組類烦磁,我們是用以Person類的name屬性為關(guān)鍵字去給Person類型的數(shù)組去排序,通過String類中的compareTo()方法按字典順序去比較字符串哼勇,首先會比較出2個字符串長度都伪。

  • 在較短的字符串長度之內(nèi),去比較兩者每一個位置上的字符是否相等积担。如果不相等院溺,則直接返回該位置上字符的ASCII碼之差,假如在第0號位置上字符相等的話磅轻,那么就去比較第1號位置上珍逸,以此類推。如果每個位置上字符的ASCII碼都相等的話聋溜,那么返回2個字符串長度之差谆膳。

public class ArrayInOb {
    private Person[] a;
    private int size;

    public ArrayInOb(int max) {
        a = new Person[max];
        size = 0;
    }

    public void insert(String name, Integer age, Integer height) {
        a[size] = new Person(name, age, height);
        size++;
    }

    public void display() {
        for (int j = 0; j < size; j++) {
            a[j].displayPerson();
        }
        System.out.println("");
    }

    public void insertSort() {
        for (int i = 0; i < size; i++) {
            Person temp = a[i];
            int j = i - 1;

            while (j >= 0 && a[j].getName().compareTo(temp.getName()) > 0) {
                a[j + 1] = a[j];
                j--;
            }

            a[j + 1] = temp;
        }
    }
}
  • 編寫測試Demo
public class ObjectSortDemo {

    public static void main(String[] args) {
        int maxSize = 100;
        ArrayInOb arrayInOb = new ArrayInOb(maxSize);

        arrayInOb.insert("garrett", 18, 173);
        arrayInOb.insert("cmazxiaoma", 21, 170);
        arrayInOb.insert("xiaodingding", 22, 165);
        arrayInOb.insert("xiaoma", 23, 155);

        System.out.println("befor sorting");
        arrayInOb.display();
        arrayInOb.insertSort();

        System.out.println("After sorting");
        arrayInOb.display();

        String a = "xiaodingding";
        String b = "xiaoma";

        System.out.println(a.compareTo(b));
    }
}
  • 運行撮躁,輸出結(jié)果漱病。很明顯看到一組Person對象是按name屬性去排序,從小到大。另外"xiaodingding""xiaoma"2個字符串比較杨帽,在比較第0 - 3個元素時昔瞧,也就是"xiao"這個4字符時蜒犯,它們都相等。可是比較到第4個元素時枪向,也就是"d""m"時虚婿。“d”ASCII碼是100屋剑,“m”ASCII碼是109茵臭。它們ASCII碼之間差值是-9,調(diào)用compareTo()結(jié)果也就是-9胧砰。所以”xiaodingding”要排在”xiaoma”的前面鳍鸵。
image.png

關(guān)于插入排序的題目

題目是這樣的。有一個有序的方法用來刪除數(shù)組中相同的數(shù)據(jù)項尉间,要求使用插入排序偿乖。

解題思路
  • 插入排序算法中用一個循環(huán)嵌套算法,將數(shù)組中的每一個數(shù)據(jù)項與其他數(shù)據(jù)項一一比較哲嘲。

  • 當(dāng)找到一個重復(fù)數(shù)據(jù)項的時候贪薪,通常用一個小于任何值的關(guān)鍵字才改寫這個相同項(如果所有值都是正數(shù),那么可以取-1)撤蚊。

  • 一般的插入排序算法就會像處理其他數(shù)據(jù)項一樣古掏,來處理這個修改了關(guān)鍵值的數(shù)據(jù)項,把它移動下標為0的位置侦啸。從現(xiàn)在開始槽唾,算法可以忽略這個數(shù)據(jù)項,下一個相同的數(shù)據(jù)項將被移動到下標為1的位置光涂,以此類推庞萍。

  • 排序完成之后,所有相同的數(shù)據(jù)項(關(guān)鍵字為-1)都在數(shù)組的開頭部分忘闻,可以改變數(shù)組的容量并把需要的數(shù)據(jù)前移到數(shù)組下標為0的位置钝计。

手寫代碼
public class InsertSortDemo {

    public static int a[] = new int[] { 11, 20, 5, 5, 1, 1, 2, 10, 20, 9 };

    public static void main(String[] args) {
        insertSortDeleteRepeatElement();
    }

    public static void insertSortDeleteRepeatElement() {
        int count = a.length;

        int repeatCount = 0;

        for (int i = 0; i < count; i++) {
            int temp = a[i];
            int j = i - 1;

            while (j >= 0 && a[j] >= temp && a[j] != -1) {
                if (a[j] == temp) {
                    temp = -1;
                    repeatCount++;
                }

                a[j + 1] = a[j];
                j--;
            }
            a[j + 1] = temp;
        }

        count -= repeatCount;

        for (int k = 0; k < count; k++) {
            a[k] = a[k + repeatCount];
        }

        for (int k = a.length - 1; k >= count; k--) {
            a[k] = 0;
        }

        display(count);
    }

    public static void display(int count) {

        for (int i = 0; i < count; i++) {
            System.out.print(a[i] + " ");
        }
        System.out.println("");
    }
}
  • 運行,輸出結(jié)果齐佳。這一題的關(guān)鍵就是找出重復(fù)的元素并且賦值為-1私恬,while()循環(huán)的時候過濾到-1的數(shù)據(jù)項,把整個數(shù)組向前移動repeatCount個單位長度并且縮小數(shù)組容量炼吴。
    image.png

尾言

咸魚也有出頭天本鸣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市硅蹦,隨后出現(xiàn)的幾起案子荣德,更是在濱河造成了極大的恐慌闷煤,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涮瞻,死亡現(xiàn)場離奇詭異鲤拿,居然都是意外死亡,警方通過查閱死者的電腦和手機署咽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門近顷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人艇抠,你說我怎么就攤上這事幕庐【米叮” “怎么了家淤?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長瑟由。 經(jīng)常有香客問我絮重,道長,這世上最難降的妖魔是什么歹苦? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任青伤,我火速辦了婚禮,結(jié)果婚禮上殴瘦,老公的妹妹穿的比我還像新娘狠角。我一直安慰自己,他們只是感情好蚪腋,可當(dāng)我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布丰歌。 她就那樣靜靜地躺著,像睡著了一般屉凯。 火紅的嫁衣襯著肌膚如雪立帖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天悠砚,我揣著相機與錄音晓勇,去河邊找鬼。 笑死灌旧,一個胖子當(dāng)著我的面吹牛绑咱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播枢泰,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼描融,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了宗苍?” 一聲冷哼從身側(cè)響起稼稿,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤薄榛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后让歼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體敞恋,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年谋右,在試婚紗的時候發(fā)現(xiàn)自己被綠了硬猫。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡改执,死狀恐怖啸蜜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情辈挂,我是刑警寧澤衬横,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站终蒂,受9級特大地震影響蜂林,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拇泣,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一噪叙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧霉翔,春花似錦睁蕾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至葱弟,卻和暖如春壹店,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背芝加。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工硅卢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人藏杖。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓将塑,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蝌麸。 傳聞我的和親對象是個殘疾皇子点寥,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容

  • 概述排序有內(nèi)部排序和外部排序,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進行排序来吩,而外部排序是因排序的數(shù)據(jù)很大敢辩,一次不能容納全部的...
    Luc_閱讀 2,259評論 0 35
  • 概述 排序有內(nèi)部排序和外部排序蔽莱,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進行排序,而外部排序是因排序的數(shù)據(jù)很大戚长,一次不能容納全部...
    蟻前閱讀 5,170評論 0 52
  • 概述:排序有內(nèi)部排序和外部排序盗冷,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進行排序,而外部排序是因排序的數(shù)據(jù)很大同廉,一次不能容納全部...
    每天刷兩次牙閱讀 3,729評論 0 15
  • 一仪糖、產(chǎn)品介紹 1.1 產(chǎn)品定位 知乎的產(chǎn)品定位是分享專業(yè)知識、經(jīng)驗和見解的問答社區(qū)迫肖,憑借著高質(zhì)量的內(nèi)容和友好理性的...
    imcby閱讀 1,595評論 0 9
  • 幾渚梁夢杯中盡蟆湖,獨影朱閣淚成詩故爵?萬里嬋娟銀河墜,星辰似海踏歌來帐姻。故夢千里清鈴響稠集,靜候梵音斬紅塵奶段〖⒋桑——題記。 那一世...
    一個文藝小青年閱讀 448評論 0 0