归并排序知识点
时间复杂度
归并排序的形式就是一棵二叉树,它需要遍历的次数就是二叉树的深度,而根据完全二叉树的可以得出它的时间复杂度是O(n*log2n)。
空间复杂度
由前面的算法说明可知,算法处理过程中,需要一个大小为n的临时存储空间用以保存合并序列。
算法稳定性
在归并排序中,相等的元素的顺序不会改变,所以它是稳定的算法。
归并排序和堆排序、快速排序的比较
若从空间复杂度来考虑:首选堆排序,其次是快速排序,最后是归并排序。
若从稳定性来考虑,应选取归并排序,因为堆排序和快速排序都是不稳定的。
若从平均情况下的排序速度考虑,应该选择快速排序。
void Merge(vector<int> &nums, int start, int middle, int end, vector<int> &buffer)
{
int i = start;
int j = middle + 1;
int k = start;
while(i <= middle && j <= end)
{
if(nums[i] <= nums[j])
buffer[k++] = nums[i++];
else buffer[k++] = nums[j++];
}
while(i <= middle)
buffer[k++] = nums[i++];
while(j <= end)
buffer[k++] = nums[j++];
for(i = start; i <= end; ++i)
nums[i] = buffer[i];
}
void MergeSort(vector<int> &nums, int start, int end, vector<int> &buffer)
{
if(start >= end) return;
int middle = (start & end) + ((start ^ end) >> 1);
MergeSort(nums, start, middle, buffer);
MergeSort(nums, middle+1, end, buffer);
Merge(nums, start, middle, end, buffer);
}
void print(const vector<int> &nums)
{
for(int i = 0; i < nums.size(); ++i)
cout<<nums[i]<<" ";
cout<<endl;
}
void MergeMain(vector<int> &nums)
{
int size = nums.size();
if(size <= 1) return;
vector<int> buffer(size, 0);
MergeSort(nums, 0, size-1, buffer);
}
int main()
{
int arr[] = {
8, 10, 9, 3, 7, 8, 9, 4, 6, 2, 5
};
vector<int> nums(arr, arr + sizeof(arr)/sizeof(int));
MergeMain(nums);
print(nums);
return 0;
}
/*************************************************************************
> File Name: TheSmallestDifference.cpp
> Author: Shaojie Kang
> Mail: kangshaojie@ict.ac.cn
> Created Time: 2015年09月07日 星期一 14时50分51秒
> Problem:
Given two array of integers(the first array is array A, the second array is array B), now we are going
to find a element in array A which is A[i], and another element in array B which is B[j], so that the
difference between A[i] and B[j] (|A[i] - B[j]|) is as small as possible, return their smallest difference.
Have you met this question in a real interview? Yes
Example
For example, given array A = [3,6,7,4], B = [2,8,9,3], return 0
Challenge
O(n log n) time
> Solution 1:
Step 1: sort the two arrays;
Step 2: use two pointers i and j which correspodingly point to the two arrays
> Solution 2:
use Binary Search, STL function lower_bound
************************************************************************/
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstdlib>
using namespace std;
// Solution 1: use two pointers
int smallestDifference(vector<int> &A, vector<int> &B)
{
int size1 = A.size();
int size2 = B.size();
if(A.empty() || B.empty()) return -1;
sort(A.begin(), A.end());
sort(B.begin(), B.end());
int i = 0, j = 0;
int smallestDiff = abs(A[0] - B[0]);
while(i < size1 && j < size2)
{
int diff = abs(A[i] - B[j]);
smallestDiff = min(smallestDiff, diff);
if(A[i] == B[j]) return 0;
else if(A[i] < B[j]) i++;
else j++;
}
return smallestDiff;
}
// Solution 2: use Binary Search
int smallestDifference2(vector<int> &A, vector<int> &B)
{
int sizeA = A.size();
int sizeB = B.size();
if(sizeA == 0 || sizeB == 0) return -1;
sort(B.begin(), B.end());
int smallestDiff = abs(A[0] - B[0]);
for(int i = 0; i < sizeA; ++i)
{
int position = lower_bound(B.begin(), B.end(), A[i]) - B.begin();
if(position != sizeB)
smallestDiff = min(smallestDiff, abs(A[i] - B[position]));
if(position != sizeB - 1)
smallestDiff = min(smallestDiff, abs(A[i] - B[position + 1]));
if(position != 0)
smallestDiff = min(smallestDiff, abs(A[i] - B[position-1]));
}
return smallestDiff;
}