排序算法及其优化总结

#include <iostream>
#include <vector>
using namespace std;

void print_td1(vector<int> nums);

// 插入排序
void insertSort(vector<int>& nums){
    int sz = nums.size();
    for(int i = 1; i < sz; i ++){
        for(int j = i; j > 0 && nums[j] < nums[j - 1]; j--){
//            if(nums[j] < nums[j - 1]){
                swap(nums[j], nums[j - 1]);
//            }
        }
    }
}
// 插入排序优化
void insertSort1(vector<int>& nums){
    int sz = nums.size();
    for(int i = 1; i < sz; i++){
        int tmp = nums[i];
        int j = i;
        for(; j > 0 && nums[j - 1] > tmp; j--){
            swap(nums[j], nums[j - 1]);
        }
        nums[j] = tmp;
    }
}

// 冒泡排序
void bubbleSort(vector<int>& nums){
    int sz = nums.size();
    for(int i = 0; i < sz; i++){
        for(int j = sz - 1; j > 0; j--){
            if(nums[j] < nums[j - 1])
                swap(nums[j - 1], nums[j]);
        }
    }
}

// 冒泡排序优化
void bubbleSort1(vector<int>& nums){
    int sz = nums.size();
    int change_id = sz - 1;    // 记录最后一个改变的id
    for(int i = 0; i < sz; i++){
        int last_id = change_id;    // i中所有内循环结束才改变最终changeid,所以要用一个新变量记录
        for(int j = 0; j < last_id; j++){
            if(nums[j] > nums[j + 1]){
                swap(nums[j], nums[j + 1]);
                change_id = j;
            }
        }
        if(change_id == i) break;
    }
}

// 选择排序
void selectSort(vector<int>& nums){
    int sz = nums.size();
    for(int i = 0; i < sz; i++){
        int index = i;
        for(int j = i + 1; j < sz; j++)
            if(nums[j] < nums[index])
                index = j;
        if(index != i)
            swap(nums[i], nums[index]);
    }
}
// 选择排序优化
void selectSort1(vector<int>& nums){
    int sz = nums.size();
    int maxpos = 0, minpos = 0;
    for(int i = 0; i < sz / 2; i++){     // 注意此处只需要遍历一半元素
        maxpos = i; minpos = i;
        for(int j = i + 1; j < sz - i; j++){
            if(nums[j] > nums[maxpos])
            {
                maxpos = j;
                continue;
            }
            if(nums[j] < nums[minpos])
                minpos = j;
        }
        if(minpos != i)
            swap(nums[i], nums[minpos]);
        if(maxpos == i)         // 如果maxpos == i,則在上一步中已經和minpos位置的元素調換了位置
            maxpos = minpos;    // 当前minpos 处的元素为原来maxpos的元素
        if(maxpos != sz - i - 1){     //数组末尾位置保存但前最大值,次小值向前插
            swap(nums[maxpos], nums[sz - i - 1]);
        }
    }
}
//归并排序
namespace mergeSort{

    void merge(vector<int>& res, int start, int end){
        vector<int> nums(res.size(), 0);
        int curr = start, l1 = start, r2 = end, mid = (start + end)>>1;
        int r1 = mid, l2 = mid + 1;
        while(l1 <= r1 && l2 <= r2){
            if(res[l1] < res[l2]) {
                nums[curr++] = res[l1++];
            }
            else {
                nums[curr++] = res[l2++];
            }
        }
        while(l1 <= r1){
            nums[curr++] = res[l1++];
        }
        while(l2 <= r2){
            nums[curr++] = res[l2++];
        }
        for(int i = start; i <= end; i++){
            res[i] = nums[i];
        }
    }

    void mergeSort(vector<int> & res, int start, int end){
        if(end < start) return;
        if(start < end){
            int mid = (start + end) >> 1;
            mergeSort(res, start, mid);   // 左开右闭
            mergeSort(res, mid + 1, end);
            merge(res, start, end);
        }
    }
}

// 快速排序

int Median3(vector<int> array, int Left, int Right) {
    int Center = Left + (Right - Left) / 2;//避免数据类型溢出
    if(array[Left] > array[Center])
        swap(array[Left], array[Center]);
    if(array[Left] > array[Right])
        swap(array[Left], array[Right]);
    if(array[Center] > array[Right])
        swap(array[Center], array[Right]);
    // Invariant : array[Left] <= array[Center] <= array[Right]
    swap(array[Center], array[Right - 1]);//Hide pivot
    return array[Right - 1];// Return pivot
}

void QuickSort(vector<int>& nums, int Left, int Right){
    if(Left >= Right)     // 终止条件,不加会无限循环
        return;
    int l = Left;
    int r = Right;
    int pivot = Median3(nums, Left, Right);
    while(l != r){
        while(nums[r] >= pivot && l < r)   // 必须先从右边开始
            r--;
        while(nums[l] <= pivot && l < r)
            l++;
        if(l < r)
            swap(nums[l], nums[r]);
    }
    swap(nums[Left], nums[l]);    // 将枢轴元素放到对应位置(初始是在数组头位置)
    QuickSort(nums, Left, l - 1);
    QuickSort(nums, l + 1, Right);
}

// 希尔排序

void ShellSort(vector<int>& nums)
{
    int sz = nums.size();
    int h = 1;
    while(h < sz / 3){
        h = h * 3  +1;
    }
    while(h >= 1){
        for(int i = h; i < sz; i++){
            for(int j = i; j >= h && nums[j] < nums[j - h]; j -= h)
                swap(nums[j], nums[j - h]);
        }
        h = h / 3;
    }
}

// 堆排序
namespace HeapSort {

    void max_heapify(vector<int>& nums, int start, int end){
        int father = start;
        int son = father * 2 + 1;
        while(son <= end)
        {
            if(son + 1 <= end && nums[son + 1] > nums[son])
                son++;
            if(nums[father] > nums[son])
                return;
            else{
                swap(nums[father], nums[son]);
                father = son;
                son = father * 2 + 1;
            }
        }
    }

    void HeapSort(vector<int>& nums) {
        int sz = nums.size();
        for(int i = sz /2 - 1; i >= 0; i--)  // i = sz/2-1,从倒数第一个非叶节点开始初始化,与孩子做比较
            max_heapify(nums, i, sz - 1);
        //先将堆顶元素和已排好元素前一位(从尾至头)做交换,再重新调整,直到排序完毕
        for(int i = sz - 1; i > 0; i--){
            swap(nums[0], nums[i]);
            max_heapify(nums, 0, i - 1);
        }
    }
}

void print_td1(vector<int> nums)
{
    int sz = nums.size();
    for(int i = 0; i < sz; i++)
    {
        cout << nums[i] << " ";
    }
}

void print_td1(int nums[], int sz){

    for(int i = 0; i < sz; i++)
    {
        cout << nums[i] << " ";
    }
}

int main()
{
    int a[] = {2,3,4,5,1};
    vector<int> test(a, a+5);
//    mergeSort::mergeSort(test, 0 , 4);
//    ShellSort(test);
    HeapSort::HeapSort(test);
    print_td1(test);
//    print_td1(a,5);
    return 0;
}
posted @ 2019-07-17 14:32  lllittletree  阅读(412)  评论(0编辑  收藏  举报