zoukankan      html  css  js  c++  java
  • 我要好offer之 排序算法大总结

    1. 插入排序

    (1) 直接插入排序

    void StraightInsertionSort(std::vector<int>& num) {
        if (num.size() == 0 || num.size() == 1) return;
        for (int i = 1; i < num.size(); ++i) {
            int tmp = num.at(i);
            int j = i - 1;
            for (; j >= 0 && num.at(j) > tmp; --j) {
                num.at(j + 1) = num.at(j); 
            }
            num.at(j + 1) = tmp;
        }
    }

    (2) 折半插入排序

    void BinaryInsertionSort(std::vector<int>& num) {
        if (num.size() == 0 || num.size() == 1) return;
        for (int i = 1; i < num.size(); ++i) {
            int tmp = num.at(i);
            int first = 0;   // 最终的first值即为插入位置
            int last = i - 1;
            while (first <= last) {
                int mid = first + (last - first) / 2;
                if (num.at(mid) < tmp) {
                    first = mid + 1;
                } else if (num.at(mid) > tmp) {
                    last = mid - 1;
                } else {
                    first = mid;
                    break;
                }
            }
            
            for (int t = i - 1; t >= first; --t) {
                num.at(t + 1) = num.at(t);
            }
            num.at(first) = tmp;
        }
    }

    2. 希尔排序

    void ShellSort(std::vector<int>& num) {
        if (num.size() == 0 || num.size() == 1) return;
        for (int gap = num.size() / 2; gap > 0; gap /= 2) {
            for (int i = gap; i < num.size(); ++i) {
                for (int j = i - gap; j >= 0 && num.at(j) > num.at(j + gap); j -= gap) {
                    std::swap(num.at(j), num.at(j + gap));
                }
            }
        }
    }

    3. 冒泡排序

    void BubbleSort(std::vector<int>& num) {
        if (num.size() == 0 || num.size() == 1) return;
        for (int i = 0; i < num.size(); ++i) {
            for (int j = 0; j < num.size() - i - 1; ++j) {
                if (num.at(j) > num.at(j + 1)) {
                    std::swap(num.at(j), num.at(j + 1));
                }
            }
        }
    }

    4. 快速排序

    (1) 递归版

    // 划分
    int Partition(std::vector<int>& num, int first, int last) {
        assert(first >= 0 && first < num.size() && last >= 0 && last < num.size() && first <= last);
        int mid = first + (last - first) / 2;
        std::swap(num.at(first), num.at(mid));
        int pos = first;
        for (int i = first; i <= last; ++i) {
            if (num.at(i) < num.at(first)) {
                std::swap(num.at(++pos), num.at(i));
            }
        }
        std::swap(num.at(first), num.at(pos));
        return pos;
    }
    
    // 快速排序
    void quickSort(std::vector<int>& num, int first, int last) {
        if (first < last) {
            int pivotPos = Partition(num, first, last);
            quickSort(num, first, pivotPos - 1);
            quickSort(num, pivotPos + 1, last);
        }
    }
    
    void QuickSort(std::vector<int>& num) {
        quickSort(num, 0, num.size() - 1);
    }

    (2) 非递归版

    int Partition(std::vector<int>& num, int first, int last) {
        assert(first >= 0 && first < num.size() && last >= 0 && last < num.size() && first <= last);
        int mid = first + (last - first) / 2;
        std::swap(num.at(first), num.at(mid));
        int pos = first;
        for (int i = first; i <= last; ++i) {
            if (num.at(i) < num.at(first)) {
                std::swap(num.at(++pos), num.at(i));
            }
        }
        std::swap(num.at(first), num.at(pos));
        return pos;
    }
    
    void QuickSort(std::vector<int>& num, int first, int last) {
        if (first < last) {
            std::stack<int> stk;
            int pivotPos = Partition(num, first, last);
            if (first < pivotPos - 1) {
                stk.push(first);
                stk.push(pivotPos - 1);
            }
            if (last > pivotPos + 1) {
                stk.push(pivotPos + 1);
                stk.push(last);
            }
            while (!stk.empty()) {
                int right = stk.top();
                stk.pop();
                int left = stk.top();
                stk.pop();
                pivotPos = Partition(num, left, right);
                if (left < pivotPos - 1) {
                    stk.push(left);
                    stk.push(pivotPos - 1);
                }
                if (right > pivotPos + 1) {
                    stk.push(pivotPos + 1);
                    stk.push(right);
                }
            }
        }
    }

    5. 简单选择排序

    void SimpleSelectSort(std::vector<int>& num) {
        if (num.size() == 0 || num.size() == 1) return;
        for (int i = 0; i < num.size(); ++i) {
            for (int j = i + 1; j < num.size(); ++j) {
                if (num.at(j) < num.at(i)) {
                    std::swap(num.at(i), num.at(j));
                }
            }
        }
    }

    6. 堆排序

    堆的有关操作

    // 堆调整,注意结点编号kth从1开始
    void HeapAdjust(std::vector<int>& num, int kth, int vecSize) {
        int left = 2 * kth;
        int right = 2 * kth + 1;
        int largest = INT_MIN;
        if (left <= vecSize && num.at(left - 1) > num.at(kth - 1)) {
            largest = left;
        } else {
            largest = kth;
        }
        
        if (right <= vecSize && num.at(right - 1) > num.at(largest - 1)) {
            largest = right;
        }
        if (largest != kth) {
            std::swap(num.at(kth - 1), num.at(largest - 1));
            HeapAdjust(num, largest, vecSize);
        }
    }
    
    // 建堆
    void BuildHeap(std::vector<int>& num) {
        for (int i = num.size() / 2; i >= 0; --i) {
            HeapAdjust(num, i + 1, num.size());
        }
    }
    
    // 堆排序
    void HeapSort(std::vector<int>& num) {
        BuildHeap(num);
        int vecSize = num.size();
        while (vecSize > 1) {
            std::swap(num.at(0), num.at(vecSize - 1));
            --vecSize;
            HeapAdjust(num, 1, vecSize);
        }
    }

    7. 归并排序

    void merge(std::vector<int>& num, int first, int mid, int last) {
        std::vector<int> tmp(last - first + 1, 0);
        int i = first;
        int j = mid + 1;
        int idx = 0;
        while (i <= mid && j <= last) {
            if (num.at(i) <= num.at(j)) {
                tmp.at(idx++) = num.at(i++);
            } else {
                tmp.at(idx++) = num.at(j++);
            }
        }
        while (i <= mid) {
            tmp.at(idx++) = num.at(i++);
        }
        while (j <= last) {
            tmp.at(idx++) = num.at(j++);
        }
        for (int i = first; i <= last; ++i) {
            num.at(i) = tmp.at(i - first);
        }
    }
    
    void MergeSort(std::vector<int>& num, int first, int last) {
        if (first < last) {
            int mid = first + (last -first) / 2;
            MergeSort(num, first, mid);
            MergeSort(num, mid + 1, last);
            merge(num, first, mid, last);
        }
    }

    8. 计数排序

    void CountSort(std::vector<int>& num) {
        if (num.size() == 0 || num.size() == 1) return;
        int minVal = *(std::min_element(num.begin(), num.end()));
        int maxVal = *(std::max_element(num.begin(), num.end()));
        int valRange = maxVal - minVal + 1;
        std::vector<int> count(valRange, 0);
        for (int i = 0; i < num.size(); ++i) {
            count.at(num.at(i) - minVal)++;
        }
        
        for (int i = 1; i < count.size(); ++i) {
            count.at(i) = count.at(i) + count.at(i - 1);
        }
        
        std::vector<int> tmp(num);
        
        for (int i = tmp.size() - 1; i >= 0; --i) {
            int lessNum = count.at(tmp.at(i) - minVal);
            num.at(lessNum - 1) = tmp.at(i);
            count.at(tmp.at(i) - minVal)--;
        }
    }

    小结: 

    排序算法总结-维基百科

     

  • 相关阅读:
    SVM – 线性分类器
    解决mybatis generator无法覆盖XML
    windows下IDEA的terminal配置bash命令
    mysqldump定时备份数据库
    linux清理日志脚本
    MySQL主从同步配置
    mysql binlog日志自动清理及手动删除
    linux搭建FTP服务器并整合Nginx
    mysql解除死锁状态
    git取消跟踪已版本控制的文件
  • 原文地址:https://www.cnblogs.com/wwwjieo0/p/3915717.html
Copyright © 2011-2022 走看看