zoukankan      html  css  js  c++  java
  • 排序算法及其优化总结

    #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;
    }
    
  • 相关阅读:
    [Codeforces 1178D]Prime Graph (思维+数学)
    [Codeforces 316E3]Summer Homework(线段树+斐波那契数列)
    [Codeforces 997C]Sky Full of Stars(排列组合+容斥原理)
    [HDU 3625]Examining the Rooms (第一类斯特林数)
    [Codeforces 364D]Ghd(随机算法+gcd)
    【快速幂】POJ3641
    【二分查找】POJ2456-Aggressive cows
    【判断解是否可行-二分】POJ1064-Cable master
    【动态规划/递推】BZOJ1806[IOI2007]- Miners
    【动态规划去除冗余】NOIP2010-乌龟棋
  • 原文地址:https://www.cnblogs.com/myblog1993/p/11200868.html
Copyright © 2011-2022 走看看