LintCode 463: Sort Integers (QuickSort和MergeSort 经典模板!!!)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/roufoo/article/details/89379984
  1. Sort Integers
    中文English
    Given an integer array, sort it in ascending order. Use selection sort, bubble sort, insertion sort or any O(n2) algorithm.

Example
Example 1:
Input: [3, 2, 1, 4, 5]
Output: [1, 2, 3, 4, 5]

Explanation: 
return the sorted array.

Example 2:
Input: [1, 1, 2, 1, 1]
Output: [1, 1, 1, 1, 2]

Explanation: 
return the sorted array.

解法1:
QuickSort经典模板。
注意:

  1. pivot是取值而不是取index,因为QuickSort过程中元素会交换,index会变。
  2. quickSort()刚进来要备份left=start, right=end,因为start和end会变。
  3. 所有比较left和right的地方都必须用<=,所有比较A[left]/A[right]和pivot的地方都必须用<。否则可能溢出,因为递归的时候start和end老是不变。
    代码如下。
  4. quickSort()里面一开始if(start>=end) return这里可以用>=也可以用>。但MergeSort()这个地方只能用>=。所以为了统一,这里都用>=。
class Solution {
public:
    /**
     * @param A: an integer array
     * @return: nothing
     */
    void sortIntegers(vector<int> &A) {
        int n = A.size();
        if (n == 0) return;
        
        quickSort(A, 0, n - 1);
    }
    
private:
    void quickSort(vector<int> &A, int start, int end) {
        if (start >= end) return; //这里也可以用>
        int left = start, right = end;
        int pivot = A[left + (right - left) / 2];
        
        while(left <= right) {
            while(left <= right && A[left] < pivot) {
                left++;
            }    
            while(left <= right && A[right] > pivot) {
                right--;
            }
            if (left <= right) {
                swap(A[left], A[right]);
                left++;
                right--;
            }
        }
        
        quickSort(A, start, right);
        quickSort(A, left, end);
    }
};

解法2:MergeSort经典模板。
注意:

  1. mergeSort()刚进去的地方if(start>=end) continue;这里只能用>=, 和quickSort()不同。
  2. mergeSort() 外面一定要开辟一个n长度的数组,这是mergeSort比quickSort费事的地方,因为开辟一个区间(之后还要回收)很费时间。
  3. mergeSort()进去了start和end都要备份。记得这里right=mid+1 (quickSort是right=end)。
  4. 所有的比较都用<=
  5. merge()里面最后记得把buf[]的start…end元素拷贝到A[]里面(不能直接A=buf)。
  6. mid是取index(不是取值!)。
  7. 简而言之,mergeSort的代码结构是while-if-while-while,而quickSort是while-while-while-if。
    代码如下:
class Solution {
public:
    /**
     * @param A: an integer array
     * @return: nothing
     */
    void sortIntegers(vector<int> &A) {
        int n = A.size();
        if (n == 0) return;
        vector<int> temp(n, 0);
        mergeSort(A, 0, n - 1, temp);
    }
    
private:
    void mergeSort(vector<int> &A, int start, int end, vector<int> &buf) {
        if (start >= end) return;//这里只能用>=
        int mid = start + (end - start) / 2;
        mergeSort(A, start, mid, buf);
        mergeSort(A, mid + 1, end, buf);
        merge(A, start, end, buf);
    }
    
    void merge(vector<int> &A, int start, int end, vector<int> &buf) {
        int mid = start + (end - start) / 2;
        int left = start;
        int right = mid + 1;
        int index = left;
        
        while(left <= mid && right <= end) {
            if (A[left] <= A[right]) {
                buf[index++] = A[left++];
            } else {
                buf[index++] = A[right++];
            }
        }
        
        while(left <= mid) {
            buf[index++] = A[left++];
        }
        
        while(right <= end) {
            buf[index++] = A[right++];
        }
        
        //remember to copy buf back to A
        //cannot directly use A = buf!
        for (int i = start; i <= end; ++i) {
            A[i] = buf[i];
        }
    }
};

猜你喜欢

转载自blog.csdn.net/roufoo/article/details/89379984