归并排序汇总

1.具体原理就不过多介绍了,先把C++程序设计上面的代码放上来

#include <iostream>
using namespace std;

void arraycopy(int source[], int sourceStartIndex, int target[], int targetStartIndex, int length);
void merge(int list1[], int list1Length, int list2[], int list2Length, int temp[]);
void mergeSort(int list[], int arraySize)
{
	if (arraySize > 1)
	{
		int* firstHalf = new int[arraySize / 2];
		arraycopy(list, 0, firstHalf, 0, arraySize/2);
		mergeSort(firstHalf, arraySize/2);

		int secondHalfLength = arraySize - arraySize/2;
		int* secondHalf = new int[secondHalfLength];
		arraycopy(list, arraySize/2, secondHalf, 0, secondHalfLength);
		mergeSort(secondHalf, secondHalfLength);

		int* temp = new int[arraySize];
		merge(firstHalf, arraySize/2, secondHalf, secondHalfLength, temp);
		arraycopy(temp, 0, list, 0, arraySize);

		delete[]temp; 
		delete[]secondHalf;
		delete[]firstHalf;
	}
}

void arraycopy(int source[], int sourceStartIndex, int target[], int targetStartIndex, int length)
{
	for (int i = 0; i < length; i++)
	{
		target[targetStartIndex++] = source[sourceStartIndex++];
	}
}

void merge(int list1[], int list1Length, int list2[], int list2Length, int temp[])
{
	int i = 0, j = 0, k = 0;
	while (i < list1Length && j < list2Length)
	{
		if (list1[i] < list2[j])
		{
			temp[k++] = list1[i++];
		}
		else 
		{
			temp[k++] = list2[j++];
		}
	}

	while (i < list1Length)
	{
		temp[k++] = list1[i++];
	}

	while (j < list2Length)
	{
		temp[k++] = list2[j++];
	}
}

int main()
{
	int p[] = {9, 6, 4, 5, 2, 3, 1, 7, 8, 0};
	int len = 10;
	mergeSort(p, len);
	for (int i = 0; i < len; i++)
	{
		cout<<p[i]<<" ";
	}
}
分析:这种情况下,个人觉得空间复杂度会比较大每一层都要使用new,总共logN层,空间复杂度应为O(NlogN)。

2.放上来一种设定全局变量的方法,从而使得空间复杂度为O(N)

#include <iostream>
using namespace std;

int s1[10] = {9, 6, 4, 5, 2, 3, 1, 7, 8, 0};
int s2[10];	//原数组为s1,临时数组为s2。

void merge(int low, int mid, int high);
void mergeSort(int firstIndex, int secondIndex)
{
	if (firstIndex < secondIndex)
	{
		int mid = (firstIndex+secondIndex)/2;
		mergeSort(firstIndex, mid);
		mergeSort(mid+1, secondIndex);
		merge(firstIndex, mid, secondIndex);
	}
}

void merge(int low, int mid, int high)
{
	int i = low, j = mid+1, k = low;
	while(i <= mid && j <= high)
	{
		if (s1[i] < s1[j])
		{
			s2[k++] = s1[i++];
		}
		else
		{
			s2[k++] = s1[j++];
		}
	}

	while (i <= mid)
	{
		s2[k++] = s1[i++];
	}

	while (j <= high)
	{
		s2[k++] = s1[j++];
	}
	for (int l = low; l <= high; l++)
	{
		s1[l] = s2[l];	//这个for循环不能忘,因为s2会被不断地冲洗掉!
	}
}

int main()
{
	mergeSort(0, 9);
	for (int i = 0; i < 10; i++)
	{
		cout<<s2[i]<<" ";
	}
}
3.O(1)空间合并算法

问题描述:设子数组:a[0:k-1]和a[k:n-1]已排好顺序(0 <=k<=n-1)。试设计一个合并这2个子数组为排好序的数组a[0:n-1]的算法。要求算法在最坏情况下所用的计算时间为O(n),且只用到O(1)的辅助空间。

我们用循环换位合并算法:


图中红色部分为每一步需要向左循环的数组范围,其实就是讲上面的一排数插入到下面中。

#include <iostream>
using namespace std;

int binarySearch(int list[], int key, int low, int high)
{
	int mid;
	while(low <= high)
	{
		mid = (low + high)/2;
		if (key == list[mid])
			return mid;
		else if(key > list[mid])
			low = mid + 1;
		else
			high = mid - 1;
	}
	if (key > list[mid])
	{
		return mid+1;
	}
	else 
		return mid;
}

void leftShift(int list[], int low, int high)
{
	int temp = list[low];
	for (int i = low; i < high; i++)
	{
		list[i] = list[i+1];
	}
	list[high] = temp;
}

void merge(int list[], int k, int len)
{
	int firstLow = 0;
	int secondLow = k, secondHigh = len-1;
	while (firstLow < secondLow)
	{
		int pos = binarySearch(list, list[firstLow], secondLow, secondHigh);
		leftShift(list, firstLow, pos-1);
		secondLow--;
	}
}

int main()
{
	int list[] = {1, 3, 5, 7, 2, 4, 6, 8};
	int k = 4, len = 8;
	merge(list, k, len);
	for (int i = 0; i < len; i++)
	{
		cout<<list[i]<<" ";
	}
}




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值