歸併排序(原地歸併+非遞歸歸併)

#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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章