快速排序(Quick-Sort)及优化

为什么排序算法重要?
问题系统熵决定了一个问题被解决的难易程度

快速排序的基础知识

基位赋值
基准的选择对效率的影响很大

从 c++ STL学习快速排序

  • 单边递归法
  • 无监督partition方法
  • 三点取中法
  • 小数据规模,停止快排过程
  • 使用插入排序进行首尾
 const int threshold = 16;
 inline int median(int a, int b, int c){
      if(a > b) swap(a, b);
      if(a > c) swap(a, c);
      if(b > c) swap(b, c);
      return b;
  }
  void __quick_sort(vector<int> &arr, int l, int r){
      while(r - l > threshold){
          int x = l, y = r, base = median(arr[l], arr[(l + r) / 2], arr[r]);
          do{
              while(arr[x] < base) x++;
              while(arr[y] > base) y--;
              if(x <= y){
                  swap(arr[x], arr[y]);
                  x++, y--;
              }
          } while(x <= y);
          __quick_sort(arr, x, r);
          r = y;
      }
      return;
  }
  void final_insert_sort(vector<int> &arr, int l, int r){
      int ind = l;
      for(int i = l; i <= r; i++){
          if(arr[i] < arr[ind]) ind = i;
      }
      while(ind > l){
          swap(arr[ind], arr[ind - 1]);
          --ind;
      }
      for(int i = l + 1; i <= r; i++){
          int j = i;
          while(arr[j] < arr[j - 1]){
              swap(arr[j], arr[j - 1]);
              j--;
          }
      }
      return;
  }
  void quick_sort(vector<int> &arr, int l, int r){
      __quick_sort(arr, l , r);
      final_insert_sort(arr, l ,r);
      return;
  }

经典面试题 - 快速排序基础

912. 排序数组

class Solution {
public:
    const int threshold = 16;
    inline int median(int a, int b, int c){
        if(a > b) swap(a, b);
        if(a > c) swap(a, c);
        if(b > c) swap(b, c);
        return b;
    }
    void __quick_sort(vector<int> &arr, int l, int r){
        while(r - l > threshold){
            int x = l, y = r, base = median(arr[l], arr[(l + r) / 2], arr[r]);
            do{
                while(arr[x] < base) x++;
                while(arr[y] > base) y--;
                if(x <= y){
                    swap(arr[x], arr[y]);
                    x++, y--;
                }
            } while(x <= y);
            __quick_sort(arr, x, r);
            r = y;
        }
        return;
    }
    void final_insert_sort(vector<int> &arr, int l, int r){
        int ind = l;
        for(int i = l; i <= r; i++){
            if(arr[i] < arr[ind]) ind = i;
        }
        while(ind > l){
            swap(arr[ind], arr[ind - 1]);
            --ind;
        }
        for(int i = l + 1; i <= r; i++){
            int j = i;
            while(arr[j] < arr[j - 1]){
                swap(arr[j], arr[j - 1]);
                j--;
            }
        }
        return;
    }
    void quick_sort(vector<int> &arr, int l, int r){
        __quick_sort(arr, l , r);
        final_insert_sort(arr, l ,r);
        return;
    }
    vector<int> sortArray(vector<int>& nums) {
        quick_sort(nums, 0 ,nums.size() - 1);
        return nums;
    }
};

剑指 Offer 21. 调整数组顺序使奇数位于偶数前面

class Solution {
public:
    vector<int> exchange(vector<int>& nums) {
        if(nums.size() == 0) return nums;
        int x = 0, y = nums.size() - 1;
        do{
            while(x < nums.size() && nums[x] % 2){
                x++;
            }
            while(y >= 0 && nums[y] % 2 == 0){
                y--;
            }
            if(x <= y){
                swap(nums[x], nums[y]);
                x++, y--;
            }
        } while(x <= y);

        return nums;
    }
};

148.排序链表

class Solution {
public:
    ListNode* sortList(ListNode* head) {
        if(head == NULL) return head;
        int l = head->val, r = head->val;
        double mid;
        ListNode *p = head, *q, *h1 = NULL, *h2 = NULL;
        while(p){
            l = min(p->val, l);
            r = max(p->val, r);
            p = p->next;
        }
        if(l == r) return head;
        mid = (l + r) / 2.0;
        p = head;
        while(p){
            q = p->next;
            if(p->val <= mid){
                p->next = h1;
                h1 = p;
            }else{
                p->next = h2;
                h2 = p;
            }
            p = q;
        }
        h1 = sortList(h1);
        h2 = sortList(h2);
        p = h1;
        while(p->next) p = p->next;
        p->next = h2;
        return h1;
    }
};

面试题 17.14. 最小K个数

class Solution {
public:
    int getmid(int a, int b, int c){
        if(a > b) swap(a, b);
        if(a > c) swap(a, c);
        if(b > c) swap(b, c);
        return b;
    }
    void quick_select(vector<int> &arr, int l, int r, int k){
        if(l >= r) return;
        int x = l, y = r, mid = getmid(arr[l], arr[(l + r)/2], arr[r]);
        do {
            while(arr[x] < mid) x++;
            while(arr[y] > mid) y--;
            if(x <= y){
                swap(arr[x], arr[y]);
                x++, y--;
            }
        }while(x <= y);
        if(y - l == k - 1) return; // 当左区间数量等于k,直接返回
        if(y - l >= k){ // 左区间数量大于k,继续扩大
            quick_select(arr, l, y, k);
        }else{
            quick_select(arr, x, r, k - x + l);
        }
        return;
    }

    vector<int> smallestK(vector<int>& arr, int k) {
        vector<int> ans;
        if(k == 0) return ans;
        quick_select(arr, 0, arr.size() - 1, k);
        while(k) ans.push_back(arr[--k]);
        return ans;
    }
};

95. 不同的二叉搜索树 II

class Solution {
public:
    vector<TreeNode*> dfs(int l, int r){
        vector<TreeNode*> ans;
        if(l > r){
            ans.push_back(nullptr);
            return ans;
        }

        for(int i = l; i <= r; i++){
            vector<TreeNode *> left_tree = dfs(l, i - 1);
            vector<TreeNode *> right_tree = dfs(i + 1, r);
            // eg : i = 3
            for(TreeNode* left : left_tree){ 
                for(TreeNode* right: right_tree){
                    TreeNode* t = new TreeNode(i, left, right);
                    ans.push_back(t);
                }
            }
        }
        return ans;
    }

    vector<TreeNode*> generateTrees(int n) {
        vector<TreeNode*> ans;
        if(n == 0) return ans;
        return dfs(1, n);
    }
};

394. 字符串解码

class Solution {
public:
    string decodeString(string s) {
        string ret;
        int i = 0;
        while(s[i]){
            if(s[i] < '0' || s[i] > '9'){
                ret += s[i];
                i++;
            }else{
                int num = 0;
                while(s[i] >= '0' && s[i] <= '9'){
                    num = num * 10 + s[i++] - '0';
                }
                i++;
                int l = i, r = i, cnt = 1;
                while(cnt){
                    r += 1;
                    if(s[r] == '[') cnt++;
                    else if(s[r] == ']') cnt--;
                }
                string tmp = decodeString(s.substr(l , r - l));
                while(num--) ret += tmp;
                i = r + 1;
            }
        }
        return ret;
    }
};

11.盛水最多的容器

class Solution {
public:
    int maxArea(vector<int>& height) {
        int ans = 0, i = 0, j = height.size() - 1;
        while(i < j){
            ans = max(ans, (j - i) * min(height[i], height[j]));
            if(height[i] < height[j]) i++;
            else j--;
        }
        return ans;
    }
};

239. 滑动窗口最大值

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> ans;
        if(k == 0) return ans;
        deque<int> q;

        int idx = 0;
        while(idx < nums.size()){
            if(!q.empty() && q.front() + k <= idx){
                q.pop_front();
            }
            while(!q.empty() && nums[q.back()] < nums[idx]){
                q.pop_back();
            }
            q.push_back(idx);
            idx++;
            if(idx >= k) ans.push_back(nums[q.front()]);
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值