经典排序方法实现

6 篇文章 0 订阅
3 篇文章 0 订阅
  • 冒泡排序
  • 选择排序
  • 插入排序
  • 快速排序
  • 堆排序
  • 希尔排序
  • 归并排序

这里写图片描述

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#include <unordered_map>
#include <string>

using namespace std;



vector<int> array2vector(int array[], int len) {
    vector<int> ret;
    for (int i = 0; i < len; i++) {
        ret.push_back(array[i]);
    }
    return ret;
}



void show_vector(const vector<int> &v) {
    cout << "-----------" << endl;
    for (auto num : v) {
        cout << num << " ";
    }
    cout << endl;
}

void show_vector(const vector<int> &v, string str) {
    cout << str << endl;
    show_vector(v);
}



//插入排序 时间O(n^2)
void insert_sort(vector<int> v) {
    cout << endl;
    cout << "insert_sort" << endl;
    for(int i = 1; i < v.size(); i++) {
        if (v[i] < v[i-1]) {
            int tmp = v[i];
            int index = i; //待插入下标
            for (int j = i - 1; j >= 0; j--) {
                if (v[j] > tmp) {
                    v[j+1] = v[j];
                    index = j;
                }
                else
                    break;
            }
            v[index] = tmp;
        }
    }
    show_vector(v);
}


//冒泡排序 时间O(n^2) 注意:有序优化
void bubble_sort(vector<int> nums) {
    cout << endl << "bubble_sort" << endl;
    for (int i = 1; i < nums.size(); i++) { //i:第几趟
        bool swaped = false;
        for (int j = 0; j < nums.size() - i; j++) {
            if (nums[j] > nums[j+1]) {
                int tmp = nums[j];
                nums[j] = nums[j+1];
                nums[j+1] = tmp;
                swaped = true;
            }
        }
        if (!swaped) // 当前趟没有交互,说明数列已有序,跳出循环
            break;
    }
    show_vector(nums);
}

//选择排序 时间O(n^2) 
void select_sort(vector<int> nums) {
    cout << endl << "select_sort" << endl;
    for (int i = 0; i < nums.size() - 1; i++) { //只需执行size() - 1趟排序
        int minIndex = i;   //最小元素小标
        for (int j = i+1; j < nums.size(); j++) {
            if (nums[j] < nums[minIndex])
                minIndex = j;
        }

        if (minIndex != i) {
            int tmp = nums[i];
            nums[i] = nums[minIndex];
            nums[minIndex] = tmp;

            // 整数交换 使用异或运算 不需要中间变量
            // nums[i] ^= nums[minIndex];
            // nums[minIndex] ^= nums[i];
            // nums[i] ^= nums[minIndex];
        }
    }
    show_vector(nums);

}


//快速排序 时间 O(n*log_n)
void qsort(vector<int> &nums, int left, int right);
void quick_sort(vector<int> &nums) {
    cout << endl << "quick_sort" << endl;
    qsort(nums, 0, nums.size() - 1);
    show_vector(nums);
}

void qsort(vector<int> &nums, int left, int right) {
    if (left >= right)
        return;
    int key = nums[left];
    int lp = left, rp = right;  //left point, right point
    while (lp < rp) {
        while (nums[rp] >= key && lp < rp)
            rp--;
        nums[lp] = nums[rp];    //小的数放到左边
        while (nums[lp] <= key && lp < rp)
            lp++;
        nums[rp] = nums[lp];    //打的数放右边
    }
    nums[lp] = key;

    qsort(nums, left, lp - 1);
    qsort(nums, lp + 1, right);
    return;
}

//堆排序 时间 O(n*log_n)
void max_heapify(vector<int> &nums, int start, int end) {
    int dad = start;
    int son = dad * 2 + 1;
    while (son <= end) {
        if (son + 1 <= end && nums[son] < nums[son+1]) //选取大的孩子,与父节点比较
            son++;
        if (nums[dad] >= nums[son]) //父节点比子节点大,说明调整完毕,跳出函数
            return;
        else {
            swap(nums[dad], nums[son]);
            dad = son;
            son = son * 2 + 1;
        }
    }
}

void heap_sort(vector<int> &nums) {
    cout << endl << "heap_sort" << endl;
    //建堆
    for (int i = nums.size()/2 - 1; i >= 0; i--) {
        max_heapify(nums, i, nums.size() - 1);
    }

    for (int i = nums.size() - 1; i > 0; i--) {
        swap(nums[i], nums[0]);
        max_heapify(nums, 0, i - 1);
    }
    show_vector(nums);
}


//归并排序 时间 O(n*log_n)
void merge(vector<int> &nums, vector<int> &result, int start, int end) {
    if (start >= end)
        return;
    int len = end - start;
    int mid = (len >> 1) + start;
    int start1 = start, end1 = mid;
    int start2 = mid + 1, end2 = end;
    merge(nums, result, start1, end1);
    merge(nums, result, start2, end2);

    int k = start;
    while(start1 <= end1 && start2 <= end2) {
        result[k++] = nums[start1] < nums[start2] ? nums[start1++] : nums[start2++];
    }
    while(start1 <= end1)
        result[k++] = nums[start1++];
    while(start2 <= end2)
        result[k++] = nums[start2++];

    for(k = start; k <= end; k++)
        nums[k] = result[k];
}

void merge_sort(vector<int> &nums) {
    cout << endl << "merge_sort" << endl;
    if (nums.size() <= 1)
        return;
    vector<int> result(nums.size());
    merge(nums, result, 0, nums.size() - 1);

    show_vector(result);
}


//希尔排序 时间 O(n*log_n^2)

void shell_sort(vector<int> nums) {
    cout << endl << "shell_sort" << endl;
    int gap, i, j, temp;
    for (gap = nums.size()>>1; gap > 0; gap >>= 1) { //步长减半
        for (i = gap; i < nums.size(); i++) {
            temp = nums[i];
            for (j = i - gap; j >= 0 && nums[j] > temp; j -= gap) {
                nums[j + gap] = nums[j];
            }
            nums[j + gap] = temp;
        }
    }
    show_vector(nums);
}


int main(int argc, char const *argv[])
{   
    int array[]={3,5,4,6,1,2,9,8,0,7};
    int n = sizeof(array) / sizeof(int);
    vector<int> v = array2vector(array, n);
    show_vector(v, "origin nums");

    insert_sort(v); // 非引用传参,v不变
    show_vector(v, "origin nums");

    bubble_sort(v);

    select_sort(v);

    quick_sort(v); // v have be changed
    v = array2vector(array, n);
    show_vector(v, "origin nums");



    heap_sort(v);
    v = array2vector(array, n);
    show_vector(v, "origin nums");


    merge_sort(v);
    v = array2vector(array, n);
    show_vector(v, "origin nums");

    shell_sort(v);



}

References

  1. http://wuchong.me/blog/2014/02/09/algorithm-sort-summary/
  2. https://zh.wikipedia.org/wiki/归并排序
  3. https://zh.wikipedia.org/wiki/希尔排序#.E6.AD.A5.E9.95.BF.E5.BA.8F.E5.88.97
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值