#include <iostream>
#include <string>
#include <stdio.h>
#include <string.h>
using namespace std;
void PrintArr(int * arr, int len){
for (int i = 0; i < len; i++)
cout << arr[i] << " ";
cout << endl;
}
void reverse(int * arr, int len){
int i = 0, j = len - 1;
while (i < j){
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
i++;
j--;
}
}
int BinarySearch(int* arr, int len, int target){
int left = 0, right = len - 1;
while (left <= right){
int mid = (- left + right) / 2 + left;
if (arr[mid] > target){
right = mid - 1;
}
else{
left = mid + 1;
}
}
return left;
}
//原地歸併
void merge(int * arr, int l1, int r1, int l2, int r2){
int i = r1, j = l2;
//cout << l1 << " " << r1 << " " << l2 << " " << r2 << endl;
PrintArr(arr, 6);
while (j <= r2){
int index1 = BinarySearch(arr, i - l1 + 1, arr[j]);
if (index1 > i){
return;
}
else {
int index2 = BinarySearch(arr + j, r2 - j + 1, arr[index1]);
if (index2 == 0){
reverse(arr + index1, i - index1 + 1);
reverse(arr + index1, i - index1 + 2);
i++;
j++;
}
else {
reverse(arr + index1, i - index1 + 1);
reverse(arr + j, index2);
reverse(arr + index1, i - index1 + 1 + index2);
i += index2;
j += index2;
}
//cout << index2 << endl;
}
}
}
/**
*歸併排序
**/
void MergeSort(int * arr, int len, int start, int end){
if (start >= end){
return;
}
int mid = start + (end - start) / 2;
MergeSort(arr, len, start, mid);
MergeSort(arr, len, mid + 1, end);
merge(arr, start, mid, mid + 1, end);
//藉助輔助空間進行歸併
#if 0
int tmp[len] = {0};
int index = 0;
int i = start, j = mid + 1;
while (i <= mid && j <= end){
if (arr[i] <= arr[j]){
tmp[index++] = arr[i++];
}
else {
tmp[index++] = arr[j++];
}
}
while (i <= mid)
tmp[index++] = arr[i++];
while (j <= end)
tmp[index++] = arr[j++];
for (int k = 0; k < index; k++)
arr[start+k] = tmp[k];
#endif
}
//非遞歸歸併
void merge1(vector<int> & nums, int lefts, int lefte, int rights, int righte){
int size = lefte - lefts + 1 + righte - rights + 1;
vector<int> tmp(size);
int i = lefts, j = rights;
int index = 0;
while (i <= lefte && j <= righte) {
if (nums[i] < nums[j]){
tmp[index++] = nums[i];
i++;
}else{
tmp[index++] = nums[j];
j++;
}
}
while (i <= lefte) {
tmp[index++] = nums[i++];
}
while (j <= righte) {
tmp[index++] = nums[j++];
}
for(int i = 0; i < size; i++){
nums[lefts+i] = tmp[i];
}
}
void MergeSort1(vector<int> & nums){
int len = nums.size();
int step = 2;
for (step = 2; step <= len; step *= 2){
for (int i = 0; i < len; i += step){
int j = i + step / 2 - 1;
if (j < len - 1){
merge1(nums, i, j, j + 1, min(i+step-1, len-1));
}
}
}
//多餘部分重新排序
if (len & (len-1)){
int remain = step / 2;
merge1(nums, 0, remain-1, remain, len-1);
}
}
int main(){
int arr[6] = {5, 4, 0, 9, 7, 1};
MergeSort(arr, 4, 0, 5);
PrintArr(arr, 6);
return 0;
}