手撕经典排序算法

直接插入排序

第一个结点默认已序,从第二个结点开始,即i=1。每次使用一个tmp报错第i个结点,然后依次将tmp与第[i-1 ~ 0]的元素进行比较,如果tmp小于其元素,则依次后移。直到找打插入位置。


void InsertionSort(vector<int> &data){
    for(int i = 1;i<data.size();++i){
        int tmp = data[i];
        for(int j = i;j>0&&tmp<data[j-1];--j){
            data[j]=data[j-1]; //向后覆盖
        }
        data[j]=tmp;
    }
}

折半插入排序(稳定的)

思路与直接插入相同,只是查找插入位置的方法不同,这里使用折半查找法查找插入点。查找到之后,一次性将所有元素后移以为,然后插入元素。
这里有个疑问:为什么取low<=high?

void InsertionSort(vector<int> &data){
    for(int i = 1;i<data.size();++i){
        int tmp = data[i];
        int low = 0,high=i-1;
        while(low<=high){//为什么取等号?
            int mid = (low+high)/2;
            if(data[mid]>tmp) high=mid-1;
            else low=mid+1;
        }

        for(j = i-1;j>=high+1;--j){
            data[j+1]=data[j];
        }
        data[high+i]=tmp;
    }
}

希尔排序(不稳定)?

希尔排序是直接插入排序的优化版


void ShellSort(vector<int> &data){
    int len = data.size();
    for(int dk = len/2;dk>=1;dk=dk/2){
        for(int i = dk+1;i<n;++i){
            if(data[i]<data[i-dk]){
                int tmp = data[i];
                for(int j = i-dk;j>=0&&tmp<data[j];j-=dk){
                    data[j+dk] = data[j];
                }
                data[j+dk] = tmp;
            }
        }
    }
}

冒泡排序

i从0开始到n-2;
j从n-1开始到i+1,运行条件为j>i或者flag = false
遇到data[j]<data[j-1]不断交换,每一趟都能过把最元素放到最终的位置


void BubbleSort(vector<int> &data){
    bool flag = true;
    for(int i = 0;i<data.size()-1 && flag;++i){ //若flag为false,停止,表示上一趟没有交换
        for(int j = data.size()-1,flag=false;j>i;--j){
            if(data[j]<data[j-1]){
                swap(data[i],data[j-1]);//小的往前移动,每次最小的都能过到最后的位置
                flag = true; //只要有交换,就设置成true
            }
        }
    }
}

快速排序

#python实现
def quik_sort(data):
    if len(num)<2: //包含[],[x]的情况
        return data
    else:
        pivot = data[0]
        less = [x for x in data[1:] if x <=pivot]
        greater = [x for x in data[1:] if x >pivot]
        return quik_sort(less)+pivot+quik_sort(greater)

#C++实现
//划分(主要)
int Partition(vector<int> &data,int low,int high){
    int pivot = data[low];
    while(low<high){
        while(low<high&&data[high]>=pivot) --high;
        data[low]=data[high];//此时low空出来了
        while(low<high&&data[low]<=pivot) ++low;
        data[high]=data[low];//此时high空出来了
    }
    data[low] = pivot; //排序
    return low;
}

void QuikSort(vector<int> &data,int low,int high){
    if(low<high){
        int pivot_pos = Partition(data,low,high);
        QuikSort(data,pivot_pos+1,high);
        QuikSort(data,low,pivot_pos-1);
    }
}

简单选择排序

void SelectSort(vector<int> &data){
    for(int i = 0;i<n-1;++i){
        int min = i;
        for(int j = i;j<n;j++){
            if(data[j]<data[min])
                min = j;
        }
        if(i!=min) swap(data[i],data[min]);
    }
}

归并排序


void Merge(vector<int> &data,int left,int mid,int right){
    auto beg = data.begin();
    vector<int> Left(beg+left,beg+m); //开辟一个辅助空间,存储左边的元素
    int i = 0; //index of Left
    int j = m,k = 0;
    while(i<Left.size()&&j<=right){
        if(Left[i] <= data[j]) data[k++] = Left[i++];
        else data[k++] = data[j++];
    }
    while(i<Left.size()) data[k++] = data[i++];
}

void MergeSort(vector<int> &data,int left,int right){
    if(left<right){
        int mid = left+(right-1)/2;
        MergeSort(data,left,mid);
        MergeSort(data,mid+1,right);
        Merge(data,left,mid,right);
    }
}

堆排序

void Heapify(vector<int> &data,int n,int i){
    int largest = i;
    int left = 2*i+1;  //左孩子
    int right = 2*i+2; //右孩子

    if(left<n && data[right]>data[largest]){ //左孩子与父节点比较大小,取大
        largest = left;
    } 
    if(right<n && data[right]>data[largest]){ //右孩子与父节点比较大小,取大
        largest = right;
    }

    if(largest != i) {
        swap(data[largest],data[i]); //交换使得父节点最大
        Heapify(data,n,largest); //递归建堆
    }
}

void HeapSort(vector<int> &data){
    int len = data.size();
    //建初始堆
    for(int i = len/2-1;i>=0;i--){//从最后一个父节点往前建立堆
        Heapify(data,len,i);
    }
    //堆排序
    for(int j = n-1;j>=0;--j){
        data[j] = data[0]; //排序
        Heapify(data,j,0);
    }
}

基数排序(来自力扣)

基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。排序过程是将所有待比较数值统一为同样的数位长度,数位较短的数前面补零,然后从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。

int getMax(int arr[], int n) 
{ 
    int mx = arr[0]; 
    for (int i = 1; i < n; i++) 
        if (arr[i] > mx) 
            mx = arr[i]; 
    return mx; 
} 

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

推荐阅读更多精彩内容