算法(Java)

一震放、排序

1.簡單選擇排序(O(n*n))

【思路】找出數(shù)組中最小的元素,將其與第一個元素交換位置驼修,然后再在剩下的元素中找出最小的元素殿遂,并與數(shù)組的第二個元素交換位置。
【特點】

原地排序乙各,不穩(wěn)定墨礁。
運行時間和輸入無關(guān)。一個已經(jīng)有序的數(shù)組和一個元素隨機排列的數(shù)組所用的時間一樣耳峦。
移動數(shù)據(jù)最少恩静。交換次數(shù)和數(shù)組大小是線性關(guān)系,每次交換都有一個元素位于正確的位置蹲坷。

import java.util.Arrays;
public class SelectSort {
    /**
     * 簡單選擇排序
     * @param a
     */
    public static void sort(int[] a) {
        for(int i =0;i<a.length;i++) {
            int minIndex = i;
            for(int j=i+1;j<a.length;j++) {
                if(a[minIndex]>a[j]) {
                    minIndex = j;
                }
            }
            if(a[i]>a[minIndex]) {
                int temp = a[i];
                a[i] = a[minIndex];
                a[minIndex] = temp;
            }
            System.out.println("第"+(i+1)+"次:"+Arrays.toString(a));
        }
    }
    public static void main(String[] args) {
        int[] a = {9,8,7,5,4,2,1};
        System.out.println("排序前:"+Arrays.toString(a));
        sort(a);
    }
}
輸出:
排序前:[9, 8, 7, 5, 4, 2, 1]
第1次:[1, 8, 7, 5, 4, 2, 9]
第2次:[1, 2, 7, 5, 4, 8, 9]
第3次:[1, 2, 4, 5, 7, 8, 9]
第4次:[1, 2, 4, 5, 7, 8, 9]
第5次:[1, 2, 4, 5, 7, 8, 9]
第6次:[1, 2, 4, 5, 7, 8, 9]
第7次:[1, 2, 4, 5, 7, 8, 9]

2.插入排序(O(n*n))

【特點】

原地排序驶乾,穩(wěn)定。
插入排序所需的時間與輸入的元素的初始順序有關(guān)循签。

import java.util.Arrays;
public class InsertSort {
    /**
     * 插入排序
     * @param a
     */
    public static void sort(int[] a) {
        for(int i = 1;i<a.length;i++) {
            for(int j=0;j<i;j++) {
                if(a[j]>a[i]) {
                    int temp = a[i];
                    for(int k = i;k>0;k--) {
                        exch(a,k,k-1);
                    }
                    a[j] = temp;
                    break;
                }
            }
            System.out.println("第"+(i)+"次:"+Arrays.toString(a));
        }
    }
    public static void  exch(int[]a ,int i,int j) {
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
    public static void main(String[] args) {
        int[] a = {9,8,7,5,4,2,2,1};
        System.out.println("排序前:"+Arrays.toString(a));
        sort(a);
    }
}

輸出:
排序前:[9, 8, 7, 5, 4, 2, 1]
第1次:[8, 9, 7, 5, 4, 2, 1]
第2次:[7, 8, 9, 5, 4, 2, 1]
第3次:[5, 7, 8, 9, 4, 2, 1]
第4次:[4, 5, 7, 8, 9, 2, 1]
第5次:[2, 4, 5, 7, 8, 9, 1]
第6次:[1, 2, 4, 5, 7, 8, 9]

3.冒泡排序(O(n*n))

【思路】遍歷數(shù)組级乐,若相鄰的兩個元素大小順序不對,交換這兩個元素的位置县匠。
【特點】

穩(wěn)定风科。
每次冒泡,會有一個數(shù)字位于正確的位置乞旦。

import java.util.Arrays;
public class BubbleSort {
    /**
     * 冒泡排序
     * @param a
     */
    public static void sort(int[] a) {//大數(shù)從數(shù)組后面冒出
        for(int i = a.length-1;i>0;i--) {
            for(int j = 0;j<i;j++) {
                if(a[j]>a[j+1]) {
                    int temp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = temp;
                }
            }
            System.out.println("第"+(a.length-i)+"次:"+Arrays.toString(a));
        }
    }
public static void sort1(int[] a) {//小數(shù)從數(shù)組前面冒出
        for(int i = 0;i<a.length;i++) {
            for(int j = a.length-1;j>i;j--) {
                if(a[j]<a[j-1]) {
                    int temp = a[j];
                    a[j] = a[j-1];
                    a[j-1] = temp;
                }
            }
            System.out.println("第"+(i+1)+"次:"+Arrays.toString(a));
        }
    }
    public static void main(String[] args) {
        int[] a = {9,8,7,5,4,2,2,1};
        System.out.println("排序前:"+Arrays.toString(a));
        sort(a);
    }
}
輸出:
排序前:[9, 8, 7, 5, 4, 2, 2, 1]
第1次:[8, 7, 5, 4, 2, 2, 1, 9]
第2次:[7, 5, 4, 2, 2, 1, 8, 9]
第3次:[5, 4, 2, 2, 1, 7, 8, 9]
第4次:[4, 2, 2, 1, 5, 7, 8, 9]
第5次:[2, 2, 1, 4, 5, 7, 8, 9]
第6次:[2, 1, 2, 4, 5, 7, 8, 9]
第7次:[1, 2, 2, 4, 5, 7, 8, 9]

4.希爾排序

【特點】

不穩(wěn)定贼穆。

package com.paixu;
import java.util.Arrays;
public class ShellSort {
    /**
     * 希爾排序
     * @param a
     */
    public static void sort(int[] a) {
        int h = 1;
        int l = a.length;
        while(h<l/3)
            h = h*3+1;
        while(h>=1) {
            for(int i=h;i<l;i++) {
                for(int j=i;j>=h;j--) {
                    if(a[j]<a[j-h]) {
                        int temp = a[j];
                        a[j] = a[j-h];
                        a[j-h] = temp;
                    }
                }
            }
            System.out.println("h="+(h)+":"+Arrays.toString(a));
            h = h/3;
        }
    }
    public static void main(String[] args) {
        int[] a = {9,8,7,5,4,2,2,1};
        System.out.println("排序前:"+Arrays.toString(a));
        sort(a);
    }
}
輸出:
排序前:[9, 8, 7, 5, 4, 2, 2, 1]
h=4:[4, 2, 2, 1, 9, 8, 7, 5]
h=1:[1, 2, 2, 4, 5, 7, 8, 9]

5.歸并(Merge)排序(N*logN)

需要額外的空間,穩(wěn)定杆查。

【】自頂向下和自底向上

6.快速排序(N*logN)

分治,將一個數(shù)組分成兩個子數(shù)組臀蛛,將其獨立排序亲桦。
【思想】以數(shù)組第一個元素(key)對元素進(jìn)行拆分,設(shè)置左右指針浊仆,分別從左邊找到第一個大于key的元素下表客峭,從右邊找出第一個大于key的元素下表,交換其位置抡柿,最后將key插入到其位置舔琅。然后修改key。

歸并排序數(shù)組是等分的洲劣,快排备蚓,切分的位置取決于數(shù)組的內(nèi)容课蔬。

【特點】
  • 不穩(wěn)定。
  • 每次切分就有一個元素處在正確的位置上郊尝。
import java.util.Arrays;
public class QuickSort {
    /**
     * 快排
     * @param args
     */

    public static void main(String[] args) {  
        int[] a = {30,25,24,31,28,46,20,40};  
        System.out.println(Arrays.toString(a));  
        quickSort(a);  
        System.out.println(Arrays.toString(a));  
    }  
    public static void quickSort(int[] a) {  
        if(a.length>0) {  
            quickSort(a, 0 , a.length-1);  
        }  
    }  
    public static void quickSort(int[] a,int low,int high) {
        if(low>high)//跳出遞歸
            return;
        int key = a[low];
        int i = low;
        int j = high;
        int temp = i;
        while(i<j) {
            while(i<j&&a[j] > key) {
                j--;                
            }
            a[i] = a[j];
            temp = i;
            while(i<j&&a[i] <= key) {
                //必須等于且i<j
                i++;
            }
            a[j] = a[i];
            temp = j;
        }
        a[temp] =key;
        System.out.println(Arrays.toString(a));
        quickSort(a,low,i-1);//key左邊快排
        quickSort(a,i+1,high);//key右邊快排
    }
    
}
輸出:
[30, 25, 24, 31, 28, 46, 20, 40]
[20, 25, 24, 28, 30, 46, 31, 40]
[20, 25, 24, 28, 30, 46, 31, 40]
[20, 24, 25, 28, 30, 46, 31, 40]
[20, 24, 25, 28, 30, 46, 31, 40]
[20, 24, 25, 28, 30, 46, 31, 40]
[20, 24, 25, 28, 30, 40, 31, 46]
[20, 24, 25, 28, 30, 31, 40, 46]
[20, 24, 25, 28, 30, 31, 40, 46]
[20, 24, 25, 28, 30, 31, 40, 46]

堆排序(完全二叉樹二跋,可以用數(shù)組實現(xiàn)而不需要指針)

不穩(wěn)定。

  • 大根堆:父節(jié)點都大于等于它的兩個兒子結(jié)點流昏。
  • 小根堆:父節(jié)點都小于等于它的兩個兒子結(jié)點扎即。
    int a[];
    int n = 0;// 數(shù)組下標(biāo)0不使用
    public Duipaixu(int maxN){
        a = new int[maxN+1]; 
    }
    public void exch(int i,int j) {
        int k = a[i];
        a[i] = a[j];
        a[j] = k;
    }
    public void insert(int k) {
        a[++n] = k;
        swim(n);
    }
    public void del(int index) {//k是數(shù)組下表
        exch(index,n--);
        sink(index);
    }
    public boolean compare(int i,int j) {
        if(a[i]>a[j])
            return false;
        else return true;
    }
    public void swim(int k){//上浮
        while(k>1&&compare(k/2,k)) {
            exch(k/2,k);
            k = k/2;
        }
    }
    public void sink(int k) {//下沉
        while(2*k<n) {
            int j = 2*k;
            if(j<n&&compare(j,j+1)) {
                j++;
            }
            exch(k,j);
            k = j;
        }
    }
    public void print() {// 輸出
        int hang = 2;
        for(int i = 1;i<=n;i++) {
            System.out.print(a[i]+" ");
            if(i == hang-1) {
                hang = hang*2;
                System.out.println();
            }
        }
    }
}

二、查找

1.二分查找(時間復(fù)雜度O(logN))

        int l0 = 0; 
        int ln = arr.length-1;
        while (l0<=ln) {
            int mid = l0+(ln-l0)/2;
            System.out.println(l0+"  "+mid+" "+ln);
            if(arr[mid] > key) {
                ln = mid-1;
            }
            else if (arr[mid] < key) {
                l0 = mid+1;
            }
            else return mid;
        }
        return -1;
    }
public static int BinarySearch(int[] a,int key,int low,int high) {// 遞歸實現(xiàn)
        int mid = low+(high-low)/2;
        if(a[mid]==key) {
            return mid;
        }
        else if(a[mid]>key) {
            return DiguiBinary(a,key,low,mid-1);
        }
        else return DiguiBinary(a,key,mid+1,high);
    }

2.二叉排序樹(時間復(fù)雜度O(logN))


3.B樹

B樹是一種多路搜索樹况凉,主要用在文件系統(tǒng)和數(shù)據(jù)庫系統(tǒng)谚鄙,文件系統(tǒng)和數(shù)據(jù)庫主要存儲在磁盤,B樹就是為了降低磁盤I/O次數(shù)刁绒。
二叉排序樹深度是logN闷营,所以時間復(fù)雜度是O(logN),要降低復(fù)雜度膛锭,就要降低樹的深度粮坞。它是一種平衡多路查找樹。


B+樹(查找兩個值之間的多個元素時)

索引都是排好序的初狰。

  • 只有最底層的節(jié)點(葉子節(jié)點)才保存信息莫杈。
  • 其它節(jié)點(非葉子結(jié)點)只是在搜索中用來指引到正確節(jié)點的。
  • 結(jié)點個數(shù)多了一倍
  • 葉子結(jié)點跟后續(xù)葉子結(jié)點是連接的奢入,
  • 插入和刪除操作的時間復(fù)雜度是 O(log(N)) 筝闹。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市腥光,隨后出現(xiàn)的幾起案子关顷,更是在濱河造成了極大的恐慌,老刑警劉巖武福,帶你破解...
    沈念sama閱讀 212,029評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件议双,死亡現(xiàn)場離奇詭異,居然都是意外死亡捉片,警方通過查閱死者的電腦和手機平痰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來伍纫,“玉大人宗雇,你說我怎么就攤上這事∮ü妫” “怎么了赔蒲?”我有些...
    開封第一講書人閱讀 157,570評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我舞虱,道長欢际,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,535評論 1 284
  • 正文 為了忘掉前任砾嫉,我火速辦了婚禮幼苛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘焕刮。我一直安慰自己舶沿,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,650評論 6 386
  • 文/花漫 我一把揭開白布配并。 她就那樣靜靜地躺著括荡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪溉旋。 梳的紋絲不亂的頭發(fā)上畸冲,一...
    開封第一講書人閱讀 49,850評論 1 290
  • 那天,我揣著相機與錄音观腊,去河邊找鬼邑闲。 笑死,一個胖子當(dāng)著我的面吹牛梧油,可吹牛的內(nèi)容都是我干的苫耸。 我是一名探鬼主播,決...
    沈念sama閱讀 39,006評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼儡陨,長吁一口氣:“原來是場噩夢啊……” “哼褪子!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起骗村,我...
    開封第一講書人閱讀 37,747評論 0 268
  • 序言:老撾萬榮一對情侶失蹤嫌褪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后胚股,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體笼痛,經(jīng)...
    沈念sama閱讀 44,207評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,536評論 2 327
  • 正文 我和宋清朗相戀三年琅拌,在試婚紗的時候發(fā)現(xiàn)自己被綠了缨伊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,683評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡财忽,死狀恐怖倘核,靈堂內(nèi)的尸體忽然破棺而出泣侮,到底是詐尸還是另有隱情即彪,我是刑警寧澤,帶...
    沈念sama閱讀 34,342評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站隶校,受9級特大地震影響漏益,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜深胳,卻給世界環(huán)境...
    茶點故事閱讀 39,964評論 3 315
  • 文/蒙蒙 一绰疤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧舞终,春花似錦轻庆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,772評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至夸盟,卻和暖如春蛾方,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背上陕。 一陣腳步聲響...
    開封第一講書人閱讀 32,004評論 1 266
  • 我被黑心中介騙來泰國打工桩砰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人释簿。 一個月前我還...
    沈念sama閱讀 46,401評論 2 360
  • 正文 我出身青樓亚隅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親辕万。 傳聞我的和親對象是個殘疾皇子枢步,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,566評論 2 349

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

  • 一些概念 數(shù)據(jù)結(jié)構(gòu)就是研究數(shù)據(jù)的邏輯結(jié)構(gòu)和物理結(jié)構(gòu)以及它們之間相互關(guān)系,并對這種結(jié)構(gòu)定義相應(yīng)的運算渐尿,而且確保經(jīng)過這...
    Winterfell_Z閱讀 5,704評論 0 13
  • 概述排序有內(nèi)部排序和外部排序醉途,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大砖茸,一次不能容納全部的...
    Luc_閱讀 2,259評論 0 35
  • 課程介紹 先修課:概率統(tǒng)計隘擎,程序設(shè)計實習(xí),集合論與圖論 后續(xù)課:算法分析與設(shè)計凉夯,編譯原理货葬,操作系統(tǒng),數(shù)據(jù)庫概論劲够,人...
    ShellyWhen閱讀 2,268評論 0 3
  • 第一章 緒論 什么是數(shù)據(jù)結(jié)構(gòu)震桶? 數(shù)據(jù)結(jié)構(gòu)的定義:數(shù)據(jù)結(jié)構(gòu)是相互之間存在一種或多種特定關(guān)系的數(shù)據(jù)元素的集合。 第二章...
    SeanCheney閱讀 5,758評論 0 19
  • 《牡丹亭》中征绎,<游園>一段六支曲子蹲姐,是如何刻畫杜麗娘心理變化的? 這六支曲子,我們一起來看看吧柴墩。 第一支【繞池游】...
    若愚2021閱讀 2,034評論 0 0