从二叉树角度看归并排序

归并排序本质上可以看作二叉树的后序遍历

里面用到的核心思想 => 分治

分:二叉树算法思想中的分解问题思想

治:链表中双指针技巧(将两条链表合并成一条有序链表)

sort首先将数组分成左半边和右半边 

=> 然后分别对左右两边再sort(递归的味道)

=>最后通过merge合并左右两边数组

将问题无限细分下去,至不能再分解(base返回),好这就到底了

开始向上返回,在向上返回的过程中不断的merge,直至顶部完成任务

放张图辅助理解一下,也帮作者推广一下

class Merge {
private:
    vector temp;
public:
    void sort(vector& nums) {
        temp.resize(nums.size());
        sort(nums, 0, nums.size() - 1);
    }
private:
    void sort(vector& nums, int left, int right) {
        if(left == right) return;
        int mid = left + (right - left) / 2;
        sort(nums, left, mid);
        sort(nums, mid + 1, right);
        merge(nums, left, mid, right);
    }
    void merge(vector& nums, int left, int mid, int right) {
        for(int i = left; i <= right; i++) {
            temp[i] = nums[i];
        }
        int p1 = left, p2 = mid + 1;
        for(int i = left; i <= right; i++) {
            if(p1 == mid + 1) nums[i] = temp[p2++];
            else if(p2 == right + 1) nums[i] = temp[p1++];
            else if(temp[p1] < temp[p2]) nums[i] = temp[p1++];
            else if(temp[p1] > temp[p2]) nums[i] = temp[p2++];
        }
    }
};

int main() {
    vector nums;
    int n;
    cin >> n;
    while(n--) {
        int num;
        cin >> num;
        nums.emplace_back(num);
    }
    (new Merge())->sort(nums);
    for(auto num: nums) {
        cout << num << " ";
    }
    return 0;
}

你可能感兴趣的:(链表,数据结构,算法)