Java排序算法

    /**
     * 直接插入排序
     * 說的簡單點,就是一組無序序列{A1,A2,........An} 先取出A1掺栅,然后從A2與A1比較,比較完之后序列狀況是{A1,A2}{A3..........An}, 
     * 其中{A1,A2}有序局装, 然后取出A3 星压,放到{A1,A2}有序序列合適位置,
     * 導致{A1,A2,A3}{A4........An}销斟。重復這個過程狼渊,直到取出An放入{A1,A2........An-1}有序序列中氧映。
     * @param a 要排序的數(shù)組
     */
    public void insertSort(int[] a) {
        int len = a.length;// 數(shù)組的長度,提升效率
        int num;//要插入的數(shù)據
        for (int i = 1; i < len; i++) {
            num = a[i];
            int k = i - 1;
            //從后向前將大于num的數(shù)據全部后移
            while (k >= 0 && a[k] > num) {
                a[k + 1] = a[k];
                k--;
            }
            //找到位置后褐缠,插入num
            a[k + 1] = num;
        }
    }

    /**
     * 希爾排序
     * 現(xiàn)在有一個array,希爾排序就是設定一個增量incrementNum(0<incrementNum<array.length)政鼠。
     * 先從array[0]開始,以incrementNum為增量的進行直接插入排序队魏,直到數(shù)組末尾公般,然后從array[1]開始重復:以incrementNum為增量的進行直接插入排序; 然后從array[1]開始重復......一直到array[n]。
     * 然后取一個小于上一步增量的新的增量(比如設置為incrementNum/2),對前一個步驟的結果array進行遍歷胡桨,直接插入排序....
     * 再取小于上一步增量的新的增量官帘,重復進行:遍歷,直接插入排序
     * 直到新的增量小于1之后再退出循環(huán)
     * @param a 要排序的數(shù)組
     */
    public void sheelSort(int[] a) {
        int len = a.length;
        int increment = len / 2;
        while (increment >= 1) {
            for (int i = 0; i < len; i++) {
                for (int k = i; k < len - increment; k += increment) {
                    if (a[k] > a[k + increment]) {
                        int temp = a[k + increment];
                        a[k + increment] = a[k];
                        a[k] = temp;
                    }
                }
                increment = increment / 2;
            }
        }
    }

    /**
     * 冒泡排序
     * 冒泡排序昧谊,就是每次遍歷都會把最小(或者最大)的數(shù)放在前面刽虹。
     * 比如要升序{A1,........An}  第一次排序要取出整個數(shù)組中最小放在A1的位置,
     * 從An開始往前遍歷呢诬,相鄰兩個數(shù)比較涌哲,如果Aj < Aj-1 則換位,直到比較到A1 這一趟完事之后, A1放的就是整個數(shù)組中最小的數(shù)尚镰。
     * 然后從A2位置開始比較阀圾,重復上一個步驟,一直比較到A2钓猬,這時候A2中放的就是整個數(shù)組中第二個小的數(shù)...........
     *
     * @param a 要排序的數(shù)序稍刀,升序排列
     */
    public void bubbleSort(int[] a) {
        int len = a.length;
        for (int i = 0; i < len; i++) {
            for (int m = len - 1; m >= i; m--) {
                if (a[m] < a[m - 1]) {
                    int temp = a[m - 1];
                    a[m] = a[m - 1];
                    a[m - 1] = temp;
                }
            }
        }
    }

    /**
     * 快速排序
     * 基本思想:基于分治的思想,是冒泡排序的改進型。首先在數(shù)組中選擇一個基準點(該基準點的選取可能影響快速排序的效率账月,后面講解選取的方法)综膀,
     * 然后分別從數(shù)組的兩端掃描數(shù)組,設兩個指示標志(lo指向起始位置局齿,hi指向末尾)剧劝,首先從后半部分開始,如果發(fā)現(xiàn)有元素比該基準點的值小抓歼,就交換lo和hi位置的值讥此,然后從前半部分開始掃秒,
     * 發(fā)現(xiàn)有元素大于基準點的值谣妻,就交換lo和hi位置的值萄喳,如此往復循環(huán),直到lo>=hi,然后把基準點的值放到hi這個位置蹋半。一次排序就完成了他巨。以后采用遞歸的方式分別對前半部分和后半部分排序,
     * 當前半部分和后半部分均有序時該數(shù)組就自然有序了减江。
     * @param a 排序數(shù)組
     * @param leftIndex 左邊開始查詢的下標
     * @param rightIndex 右邊開始查詢的下標
     */
     public void quickSort(int[] a, int leftIndex, int rightIndex) {
        int i = leftIndex;//左邊查詢下標
        int j = rightIndex;//右邊查詢下標
        int temp = a[leftIndex];//基準數(shù)值
        if (leftIndex > rightIndex) {
            return;
        }
        while (i < j) {
            //先從右邊向左查詢染突,找到第一個比temp小的值
            while (a[j] >= temp && i < j) {
                j--;
            }
            //從左邊向右查詢,找到第一個比temp大的值
            while (a[i] <= temp && i < j) {
                i++;
            }
            //滿足條件辈灼,則交換兩個位置的值
            if (i < j) {
                int t = a[j];
                a[j] = a[i];
                a[i] = t;
            }
        }
        //交換基準位置的值
        a[leftIndex] = a[i];
        a[i] = temp;
        //左邊再次來一遍查詢排序
        quickSort(a, leftIndex, j - 1);
        //右邊再次來一遍查詢排序
        quickSort(a, j + 1, rightIndex);
    }

/**
     * 選擇排序
     * 每趟找出余下數(shù)組中最小的放在前邊
     *
     * @param a 數(shù)組
     */
    private void selectSort(int[] a) {
        int len = a.length;
        for (int i = 0; i < len; i++) {//循環(huán)次數(shù)
            int num = a[i];
            int position = i;
            //循環(huán)找到最小的值份企,和下標index
            for (int k = i + 1; k < len; k++) {
                if (a[k] < num) {
                    num = a[k];
                    position = k;
                }
            }
            //交換找到的最小值和當前的位置,放在前邊
            a[position] = a[i];
            a[i] = num;
        }
    }


/**
     * 前提條件:已排序的數(shù)組中查找
     * 首先確定該查找區(qū)間的中間點位置: int mid = (low+upper) / 2巡莹;
     * 然后將待查找的值與中間點位置的值比較:若相等司志,則查找成功并返回此位置。
     * 若中間點位置值大于待查值榕莺,則新的查找區(qū)間是中間點位置的左邊區(qū)域俐芯。
     * 若中間點位置值小于待查值,則新的查找區(qū)間是中間點位置的右邊區(qū)域钉鸯。下一次查找是針對新的查找區(qū)間進行的吧史。
     * 遞歸實現(xiàn)二分查找
     * @param a 數(shù)組
     * @param start 開始位置
     * @param end 結束位置
     * @param key 要查找的key
     * @return
     */
    private int binSearch(int[] a, int start, int end, int key) {
        int mid = (end - start) / 2 + start;
        if (a[mid] == key) return mid;
        if (start > end) {
            return -1;
        } else if (key < a[mid]) {
            return binSearch(a, start, mid - 1, key);
        } else if (key > a[mid]) {
            return binSearch(a, mid + 1, end, key);
        }
        return -1;
    }

    /**
     * 普通循環(huán)實現(xiàn)二分查找
     * @param a 數(shù)組
     * @param key 要查找的key
     * @return
     */
    private int binSearch(int[] a, int key) {
        int mid = a.length / 2;
        if (a[mid] == key) {
            return mid;
        }
        int start = 0;
        int end = a.length - 1;
        while (start < end) {
            mid = (end - start) / 2 + start;
            if (key < a[mid]) {
                end = mid - 1;
            } else if (key > a[mid]) {
                start = mid + 1;
            } else {
                return mid;
            }

        }
        return -1;
    }
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市唠雕,隨后出現(xiàn)的幾起案子贸营,更是在濱河造成了極大的恐慌,老刑警劉巖岩睁,帶你破解...
    沈念sama閱讀 223,207評論 6 521
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钞脂,死亡現(xiàn)場離奇詭異,居然都是意外死亡捕儒,警方通過查閱死者的電腦和手機冰啃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,455評論 3 400
  • 文/潘曉璐 我一進店門邓夕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人阎毅,你說我怎么就攤上這事焚刚。” “怎么了扇调?”我有些...
    開封第一講書人閱讀 170,031評論 0 366
  • 文/不壞的土叔 我叫張陵矿咕,是天一觀的道長。 經常有香客問我狼钮,道長碳柱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,334評論 1 300
  • 正文 為了忘掉前任熬芜,我火速辦了婚禮莲镣,結果婚禮上,老公的妹妹穿的比我還像新娘猛蔽。我一直安慰自己剥悟,他們只是感情好灵寺,可當我...
    茶點故事閱讀 69,322評論 6 398
  • 文/花漫 我一把揭開白布曼库。 她就那樣靜靜地躺著,像睡著了一般略板。 火紅的嫁衣襯著肌膚如雪毁枯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,895評論 1 314
  • 那天叮称,我揣著相機與錄音种玛,去河邊找鬼。 笑死瓤檐,一個胖子當著我的面吹牛赂韵,可吹牛的內容都是我干的。 我是一名探鬼主播挠蛉,決...
    沈念sama閱讀 41,300評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼祭示,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了谴古?” 一聲冷哼從身側響起质涛,我...
    開封第一講書人閱讀 40,264評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎掰担,沒想到半個月后汇陆,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 46,784評論 1 321
  • 正文 獨居荒郊野嶺守林人離奇死亡带饱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,870評論 3 343
  • 正文 我和宋清朗相戀三年毡代,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,989評論 1 354
  • 序言:一個原本活蹦亂跳的男人離奇死亡教寂,死狀恐怖灯蝴,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情孝宗,我是刑警寧澤穷躁,帶...
    沈念sama閱讀 36,649評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站因妇,受9級特大地震影響问潭,放射性物質發(fā)生泄漏。R本人自食惡果不足惜婚被,卻給世界環(huán)境...
    茶點故事閱讀 42,331評論 3 336
  • 文/蒙蒙 一狡忙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧址芯,春花似錦灾茁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,814評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至旬陡,卻和暖如春拓颓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背描孟。 一陣腳步聲響...
    開封第一講書人閱讀 33,940評論 1 275
  • 我被黑心中介騙來泰國打工驶睦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人匿醒。 一個月前我還...
    沈念sama閱讀 49,452評論 3 379
  • 正文 我出身青樓场航,卻偏偏與公主長得像,于是被迫代替她去往敵國和親廉羔。 傳聞我的和親對象是個殘疾皇子溉痢,可洞房花燭夜當晚...
    茶點故事閱讀 45,995評論 2 361

推薦閱讀更多精彩內容

  • 直接插入算法 顧名思義,就是在有序數(shù)組中適當?shù)奈恢貌迦朐亍?算法思路:把待排序的數(shù)組蜜另,第0位的元素看做是一個排好...
    守敬閱讀 212評論 0 0
  • 歸并排序 思路:使用分治思想适室,將數(shù)組一直拆分,直到拆分成一個元素举瑰,此時每一個元素都相當于一個有序的數(shù)組捣辆,之后再將每...
    守敬閱讀 495評論 0 1
  • 冒泡排序 思路:相鄰元素進行比較,每一次將最大的元素放到數(shù)組最后邊此迅,之后進行下一輪重復操作汽畴,把最大元素移動到第一次...
    守敬閱讀 579評論 0 4
  • 一旧巾、原理 冒泡排序的時間復雜度是O(n*n)冒泡排序方式是把下標相鄰的兩個元素進行比較,從小到大進行排序忍些,下標相鄰...
    咖啡少年不加糖whm閱讀 334評論 0 0
  • 快速排序算法 思路:選擇基準數(shù)鲁猩,將所有小于基準數(shù)的移動到基準數(shù)的左邊,大于的移動到右邊罢坝,之后采用分治思想廓握,遞歸調用...
    守敬閱讀 452評論 0 2