常见排序算法,及其二分查找

直接插入排序 (稳定)O(n^2)

希尔排序(不稳定)O(nlog_2n)

冒泡排序(稳定)O(n^2)

快速排序(不稳定)O(nlog_2n)

直接选择排序(不稳定)O(n^2)

堆排序(不稳定)O(nlog_2n)

归并排序(稳定)O(nlog_2n)

基数排序(稳定)

二分查找在最下面....


直接插入: 

分析:

1,从第一个数的下一个数开始外层遍历

2,然后用当前这个数和这个数前面的所有数进行比较,比他大的数就向后移动移动,提前把这个数弄到一个temp中存储起来。

3,一直到这个数碰到比他小的数就退出,并把temp的值赋予退出这个位置

具体举例:

5,6,1,7,4,8,3,2,9

第一次:从6开始往后遍历,用6和5比较

5,6,1,7,4,8,3,2,9

第二次:用1和6比,6>1,所以6向后移动一位,1然后和5比,5>1,所以5也向后移动一位

1,5,6,7,4,8,3,2,9

第三次:用7和前面的比较

....一直类似的比较到最后

1,2,3,4,5,6,7,8,9

具体算法:

    int a[6]={1,2,3,2,1,6};

    int i,j,temp;

  // 插入排序

    for(i=1;i<N;i++){

        temp=a[i];

        for(j=i-1;j>=0;j--){

            if(a[j]>temp){

                a[j+1]=a[j];

            }else{

                break;

            }

        }

        a[j+1]=temp;

    }


希尔排序:

分析:他是一种缩小增量排序,将相隔某个增量的记录组成一个子序列,这个序列采用的直接插入排序,增量一趟一趟都在减少,知道减少到1,进行最后一次排序

比如:49  38   65   97   76   13   27   49    55    04

增量是5,3,1

一趟排序:49  38   65   97   76   13   27   49    55    04

其中 49和13,38和27,65和49...

13 27 49 55 04 49 38 65 97 76

二趟排序:

13,55,38,76排序,27,04,65排序,49,49,97排序

13 04 49 38 27 49 55 65 97 76

三趟排序:

14 13  27 38 49 49 55 65 76 97


折半插入:

void b_insert(int *a,int len){

    int i,j,temp,m,low,high;

    for(i=1;i<len;i++){

        low=0;

        high=i-1;

        while(low<=high){

            m=(low+high)/2;

            if(a[m]>a[i]){

                high=m-1;

            }else{

                low=m+1;

            }

        }

        temp=a[i];

        for(j=i;j>high+1;j--){

            a[j]=a[j-1];

        }

        a[high+1]=temp;

    }

}


冒泡排序:

分析:记录两两比较关键字,如果前面的比后面的大,就交换,每一次排序,都保证有最大的升上去了,有n个记录,外层比较次数,n-1,内层每次比较n-i-1

这个比较简单,就不举例了,直接上算法:

for(i=0;i<N-1;i++){

        int leap=1;

        for(j=0;j<N-i-1;j++){

            if(a[j]>a[j+1]){

                temp=a[j];

                a[j]=a[j+1];

                a[j+1]=temp;

                leap=0;

            }

        }

        if(leap){

            break;

        }

    }


快速排序:

分析:

1,找一个中枢记录,一般是第一个值

2,i指向第一个值,j指向最后一个值

3,如果j==i,就把中枢记录赋值给a[i]

4,如果j>i,一直循环,如果a[j]>=中枢,j--,否则,a[i]=a[j]

5,如果j>i,一直循环,如果a[i]<=中枢,i++,否则,a[j]=a[i]

6,采用递归的形式,进行排序

比如:49   38     65     97      76       13       27       49

取p=49

i=0,j=7,分别指向第一个和最后一个值

第一趟排序的过程:

27(i)    38      65      97        76      13       _j_   49

27       38      _i_       97      76     13      65(j)      49

27       38      13(i)      97      76     _j_      65     49

27       38      13      _i_      76      97(j)      65     49

完成一趟排序:27       38      13      49(i,j)     76      97     65     49

第二趟排序:

{27       38      13 }  49  { 76      97     65     49}

{13(i)      38        _j_}   49  { 49(i)     97      65     _j_}

{13       _i_       38(j)}   49  {49    _i_     65      97(j)}

{13      27      38}   49   { 49  65(i)   _j_    97}

完成两趟排序:{13      27(i,j)       38}  49   {49   65     76(i,j)     97}

......{13    27     38     49      49      65     76      97}

具体代码,有递归和非递归算法:

#include <iostream>

using namespace std;

int zhixing(int *a,int low,int high){

    int key=a[low];

    int i=low;

    int j=high;

    while(i<j){

        while(i<j && a[j]>=key){

            j--;

        }

        if(i<j){

            a[i]=a[j];

            i++;

        }

        while(i<j && a[i]<=key){

            i++;

        }

        if(i<j){

            a[j]=a[i];

            j--;

        }

    }

    a[i]=key;

    return i;

}

void kp(int *a,int low,int high){

    if(low<high){

        int p=zhixing(a,low,high);

        kp(a,0,p-1);

        kp(a,p+1,high);

    }

}

//非递归算法

void fei_kuaipai(int *a,int low,int high){

    //使用栈,来存储每次分开的列的头和尾

    //使用上面的zhixing(a,low,high)这个方法,把每次的列都排好序,low和high从栈中取出,一直到栈为空,就排完序了

    int mid=zhixing(a,low,high);//首先把这个数组分开,mid左边都是比他小的,右边都是比他大的

    //定义一个栈

    stack<int> s;

    if(low<mid-1){

        s.push(low);

        s.push(mid-1);

    }

    if(high>mid+1){

        s.push(high);

        s.push(mid+1);

    }

    while(!s.empty()){//栈为空退出循环

        low=s.top();

        s.pop();

        high=s.top();

        s.pop();

        mid=zhixing(a,low,high);//在对子序列进行排序

        if(low<mid-1){

            s.push(low);

            s.push(mid-1);

        }

        if(high>mid+1){

            s.push(high);

            s.push(mid+1);

        }

    }

}

int main()

{

    //快速排序

    int a[6]={1,2,3,4,2,1};

    kp(a,0,5);

    fei_kuaipai(a,0,5);

    int i;

    for(i=0;i<6;i++){

        cout<<a[i]<<" ";

    }

    return 0;

}


选择排序:

分析:

1,每次保证确定是最小的,从0开始遍历,每次都假设第一个数是最小的,向后遍历

2,如果碰到比这个数小的,就把下标赋值给min

3,判断一下看这个最小的是否还是刚开始的,如果不是,就把最小的和这个数交换位置

4,然后进行下次遍历,保证最前面是最小的

代码如下:

for(i=0;i<N;i++){

        int min=i;

        for(j=i+1;j<N;j++){

            if(a[j]<a[min]){

                min=j;

            }

        }

        if(min!=i){

            temp=a[i];

            a[i]=a[min];

            a[min]=temp;

        }

    }


堆排序:

构建大顶堆(父大于子),或构建小顶堆(父小于子),然后进行调整,再构建,在调整,....直到最后的根节点,排序完成。


归并排序:

2路归并排序---先对子集排序,归并

比如:

3    2     5     1      6        8      4

第一趟:{2      3}       {1        5}        {6        8 }      {4}

第二趟:{1        2        3        5  }     { 4        6        8}

第三趟:{1        2        3        4        5        6        8}


基数排序(桶排序):

分析:

从个位开始进行第一趟,下来的是从小到大排序的,每次依序进入桶中,进入完成之后,从下面依次出来,然后在从十位开始进入,...直到最后一趟,排序完成


二分查找:

分析:必须是有序序列,才可以进行二分查找,在做题的过程中可以构造折半二叉树,就是一颗二叉排序树。每次找的中间的数都是下标(a+b)/2向下取整的下标对应的数。

算法:

int min=0,max=N-1,mid=(min+max)/2;

    int n;

    scanf("%d",&n);

    while(min<=max){

        if(a[mid]==n){

            printf("%d ",mid);

            break;

        }else if(n>a[mid]){

            min=mid+1;

        }else if(n<a[mid]){

            max=mid-1;

        }

        mid=(max+min)/2;

    }

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,706评论 4 366
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,002评论 1 301
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,462评论 0 250
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,375评论 0 216
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,763评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,849评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,033评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,768评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,490评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,734评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,204评论 1 264
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,566评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,227评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,137评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,934评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,926评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,774评论 2 274

推荐阅读更多精彩内容

  • 在C语言中,五种基本数据类型存储空间长度的排列顺序是: A)char B)char=int<=float C)ch...
    夏天再来阅读 3,101评论 0 2
  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    蚁前阅读 5,108评论 0 52
  • 1、常用排序算法 2、快速排序法 基本思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比...
    Bling_ll阅读 503评论 0 0
  • 1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入到已排序好...
    依依玖玥阅读 1,179评论 0 2
  • 跟心与心工作室惠玲老师读完《接纳力》两本书,在读之前,我是先在喜马拉雅听,每天有机会就听,一遍接一遍,有...
    愿我拥有幸福的能力阅读 108评论 0 0