排序

    #import <Foundation/Foundation.h>
    /*
      選擇 插入 On2 時間復(fù)雜度
      插入排序 > 選擇排序
     */
    /*
     1.選擇排序
     
     選擇排序算法分為已排區(qū)間和未排區(qū)間,但是選擇排序每次會從未排序區(qū)間中找到最小的元素膜廊,將其放到已排區(qū)間的末尾师枣。
     選擇排序算法空間復(fù)雜度為O(1),是一種原地排序算法卢肃,選擇排序最好的時間復(fù)雜度纤控、最壞和平均都是O(n2)
     選擇排序是一種不穩(wěn)定的排序算法畜隶。(稍差)
     
     */
    
    
    /*
     2.插入排序
      1.首先將數(shù)組中的數(shù)據(jù)分為兩個區(qū)間 已排區(qū)間和未排區(qū)間
      初始已排區(qū)間只有一個元素就是數(shù)組的第一個元素蒋譬。插入算法的核心思想就是取未排序區(qū)間中的元素,在已排序區(qū)間中找到合適的
      插入位置將其插入揍诽,并保證已排序區(qū)間數(shù)據(jù)一直有序诀蓉。重復(fù)這個過程,直到未排序區(qū)間中元素為空暑脆。算法結(jié)束渠啤。
      2.兩種操作
             一種是元素的比較 一種是元素的移動
      3.移動操作次數(shù)總是固定的 等于逆序度
      4. 有序度和逆序度:
         有序度:是數(shù)組中具有有序關(guān)系的元素對的個數(shù)。
         滿有序度: n*(n-1)/2
         逆序度: 滿有序度 - 有序度
     */
    
    /*
     3.冒泡排序
      1.冒泡排序只會操作相鄰的兩個數(shù)據(jù)添吗,每次冒泡操作都會對相鄰的兩個元素進(jìn)行比較沥曹,看是否滿足大小關(guān)系,如果不滿足
     就讓他倆交換碟联。一次冒泡會讓至少一個元素移動到它應(yīng)該在的位置妓美。重復(fù)n次就完成了n個數(shù)據(jù)的排序工作。
     */
    
    /*
     分治算法
     分而治之玄帕,就是將原問題分割成同等結(jié)構(gòu)的子問題部脚,之后將子問題逐一解決后,原問題也得到解決裤纹。
     
     */
    
    
    /*
     4.歸并排序
     自頂向下歸并排序
     */
    void _merge(int arr[],int l,int mid,int r)
    {
        //將l和mid mid到r之間進(jìn)行merge
        int aux[r-l+1];
        for (int i=l; i<=r; i++) {
            aux[i-l] = arr[i];
        }
        int i = l,j = mid+1;
        for (int k=l; k<=r; k++) {
            //判斷索引
            if (i>mid) {
                arr[k] = aux[j-l];
                j++;
            }else if (j>r)
            {
                arr[k] = aux[i-l];
                i++;
            }else if (aux[i-l]<aux[j-l]) {
                arr[k] = aux[i-l];
                i++;
            }else
            {
                arr[k] = aux[j-l];
                j++;
            }
        }
    }
    
    void _mergerSort(int arr[],int l,int r)
    {
        if (l>=r) {
            return;
        }
        int mid = (l+r)/2;
        _mergerSort(arr, l, mid);
        _mergerSort(arr, mid+1, r);
        //優(yōu)化部分 無序才需要merge
        if (arr[mid]>arr[mid+1]) {
           _merge(arr, l, mid, r);
        }
    }
    
    void mergeSort(int arr[],int n)
    {
        _mergerSort(arr, 0, n-1);
    }
    
    /*
     自底向上歸并排序
     
     */
    void mergerSortBU(int arr[],int n)
    {
        for(int sz=1;sz<=n;sz+=sz)//sz 1 2 4 6 8
        {
            for(int i=0;i+sz<n;i+= sz+sz)
            {
                _merge(arr, i, i+sz-1, i+sz+sz-1);
            }
        }
    }
    
    
    /*
     快速排序
     1.選擇一個標(biāo)定點(diǎn)  分成兩塊
     最差的情況退化為O(n^2)
     nLogn
     */
    //返回p 使得arr[l...p-1]; arr[p+1,...r]>arr[p]
    int _partition(int arr[],int l,int r)
    {
        int x = random()%(r-l+1)+l;
        int v = arr[l];
         //arr[l+1,j]<v
        int j=l;
        for (int i=l+1; i<=r; i++) {
            if (arr[i]<=v) {
                //交換
                int tmp = arr[i];
                arr[i] = arr[j+1];
                arr[j+1] = tmp;
                j++;
                //增加小于V的數(shù)組大小
            }
        }
        //交換V的位置
        int tmp = arr[l];
        arr[l] = arr[j];
        arr[j] = tmp;
        return j;
    }
    
    
    void _quickSort(int arr[],int l,int r)
    {
        if (l-r <= 15) {
        
            return;
        }
        int p = _partition(arr, l, r);
        _quickSort(arr, l, p);
        _quickSort(arr, p+1, r);
        
    }
    
    
    
    
    void quickSort(int arr[],int n)
    {
        _quickSort(arr, 0, n);
    }
    
    void bubbleSort(int arr[],int n)
    {
        if (n<=1) {
            return;
        }
        for (int i=0; i<n; i++) {
            bool flag = false;//提前退出冒泡排序的標(biāo)志位
            for (int j=0; j<n-i-1; j++) {
                if (arr[j]>arr[j+1]) {
                    //交換
                    int tmp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = tmp;
                    flag = true;
                }
            }
            if (!flag) {
                break;
            }
        }
    }
    
    
    void insertSort(int arr[],int n)
    {
       if(n<=1) return;
        for(int i=1;i<n;i++)
        {
            int value = arr[i];//制作一個副本
            int j = i-1;//插入的位置
            for (;j>=0; j--) {
                if (arr[j]>value) {
                    arr[j+1] = arr[j];
                }else
                {
                    break;
                }
            }
            arr[j+1] = value;
        }
        
    }
    
    
    void selectSort(int arr[], int n)
    {
        if (n<=1) {
            return;
        }
        
        for (int i=0; i<n; i++) {
            //1.確定一個最小的下標(biāo)
            int minIndex = i;
            for (int j=i+1; j<n; j++) {
                if (arr[j]<arr[minIndex]) {
                    minIndex = j;
                }
            }
            //交換
            int tmp;
            tmp = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = tmp;
        }
    }
    
    
    int _selectionPartition(int arr[],int l,int r)
    {
        int p = rand()%(r-l+1)+1;
        
        int tmp = arr[l];
        arr[l] = arr[p];
        arr[p] = tmp;
        
        int j = l;//[l+1...j]<p;[lt+1..i]>p
        for (int i=l+1; i<=r; i++) {
            if (arr[i]<arr[l]) {
                int tmp = arr[i];
                arr[i] = arr[j+1];
                arr[j+1] = tmp;
                j++;
            }
        }
        //交換V的位置
        int tmp1 = arr[l];
        arr[l] = arr[j];
        arr[j] = tmp1;
        return j;
    }
    
    int _selection(int arr[],int l,int r,int k)
    {
        if (l == r) {
            return arr[l];
        };
        int p = _selectionPartition(arr,l,r);
        if (k == p) {//如果k == p 直接返回arr[p]
            return arr[p];
        }else if (k<p)//如果k<p 只需要在arr[l..p-1]中查找第k小元素即可。
        {
            return _selection(arr, l, p-1,k);
        }else //如果 k > p, 則需要在arr[p+1...r]中找第k-p-1小元素
        {
            return _selection(arr, p+1, r, k);
        }
    }
    
    
    //求數(shù)組中范圍內(nèi)第K(小)大的數(shù)
    void shuffleArray(int arr[],int n,int k)
    {
        int k1 =  _selection(arr, 0, n-1, k);
        printf("k的值 == %d",k1);
    }
    
    
    
    
    
    
    
    
    
    
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            int a[10]={ 8,3,2,1,6,5,4,7,10,9 };
            quickSort(a, 10);
            for(int i=0;i<10;i++)
            {
                printf("%d ",a[i]);
        }
    }
    return 0;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市鹰椒,隨后出現(xiàn)的幾起案子锡移,更是在濱河造成了極大的恐慌,老刑警劉巖漆际,帶你破解...
    沈念sama閱讀 212,029評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件淆珊,死亡現(xiàn)場離奇詭異躯概,居然都是意外死亡拒迅,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評論 3 385
  • 文/潘曉璐 我一進(jìn)店門慈迈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來擂找,“玉大人戳吝,你說我怎么就攤上這事」嵯眩” “怎么了听哭?”我有些...
    開封第一講書人閱讀 157,570評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長塘雳。 經(jīng)常有香客問我陆盘,道長,這世上最難降的妖魔是什么败明? 我笑而不...
    開封第一講書人閱讀 56,535評論 1 284
  • 正文 為了忘掉前任隘马,我火速辦了婚禮,結(jié)果婚禮上妻顶,老公的妹妹穿的比我還像新娘酸员。我一直安慰自己,他們只是感情好盈包,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,650評論 6 386
  • 文/花漫 我一把揭開白布沸呐。 她就那樣靜靜地躺著,像睡著了一般呢燥。 火紅的嫁衣襯著肌膚如雪崭添。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,850評論 1 290
  • 那天叛氨,我揣著相機(jī)與錄音呼渣,去河邊找鬼。 笑死寞埠,一個胖子當(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
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,536評論 2 327
  • 正文 我和宋清朗相戀三年裁厅,在試婚紗的時候發(fā)現(xiàn)自己被綠了冰沙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,683評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡执虹,死狀恐怖拓挥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情声畏,我是刑警寧澤撞叽,帶...
    沈念sama閱讀 34,342評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站插龄,受9級特大地震影響愿棋,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜均牢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,964評論 3 315
  • 文/蒙蒙 一糠雨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧徘跪,春花似錦甘邀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,772評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至哨查,卻和暖如春逗抑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背寒亥。 一陣腳步聲響...
    開封第一講書人閱讀 32,004評論 1 266
  • 我被黑心中介騙來泰國打工邮府, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人溉奕。 一個月前我還...
    沈念sama閱讀 46,401評論 2 360
  • 正文 我出身青樓褂傀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親加勤。 傳聞我的和親對象是個殘疾皇子仙辟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,566評論 2 349

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