归并排序(原地归并+非递归归并)

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值