数据结构学习第二十六课(归并排序)

归并排序:

两个有序数组合并为一个有序数组

步骤:

1 两个指针分别指向两个有序数组;
2 循环遍历并且比较,符合要求的数据存放到最终的内存段中,并且指针后挪;
3 直到有一个数组存放完毕,循环结束;
4 将没有放完的数组拷贝到最终的内存段中;

1 源文件


#include<stdio.h>
#include<string.h>

//归并排序
void merge_sort(int* arr, int len);

//递归拆分 left:左边一半第一个元素下标,right:右边一半最后一个元素的下标
void split(int* arr, int left, int right);

//合并 left:左边一半第一个元素下标,mid:左边一半最后一个元素下标,right:右边一半最后一个元素的下标
void combine(int* arr, int left, int mid, int right);
void print(int* arr, int len);
int main()
{
	int arr[10] = { 15,32,89,456,133,20,46,57,77,966 };

	printf("before :");
	print(arr, 10);

	merge_sort(arr, 10);

	printf("after :");
	print(arr, 10);
	return 0;
}

void merge_sort(int* arr, int len)
{
	split(arr, 0, len - 1);
}

void split(int* arr, int left, int right)
{
	if(left < right)//保证拆分到只有一个元素就停止
	{
		//算中间值
		//int mid = (right - left) / 2 + left;
		int mid = (left+right)/2;
		//拆分
		split(arr, left, mid);//拆左边
		split(arr, mid + 1, right);//拆右边
		//合并
		combine(arr, left, mid, right);

		print(arr + left, right - left + 1);
	}
}

void combine(int* arr, int left, int mid, int right)
{
	//申请临时内存段
	int len = right - left + 1;
	int* pTemp = new int[len];
	//循环比较并把数据有序放到pTemp
	int l = left;//左边一半
	int r = mid+1;//右边一半
	int k = 0;//pTemp的下标
	while (l <= mid && r <= right)
	{
		if (arr[l] < arr[r])
		{
			pTemp[k++] = arr[l++];
		}
		else
		{
			pTemp[k++] = arr[r++];
		}
	}
	//把剩下的也放到pTemp
#if 1
	while(l<=mid)pTemp[k++] = arr[l++];
	while(r<=right)pTemp[k++] = arr[r++];
#else
	if (l <= mid)//左边没放完
	{
		memcpy(pTemp + k, arr + l, sizeof(int) * (mid - l + 1));
	}
	else//右边还没有放完
	{
		memcpy(pTemp + k, arr + right, sizeof(int) * (right - r + 1));
	}
	k += (right - r + 1);
#endif
	//pTemp覆盖回arr中
	memcpy(arr + left, pTemp, sizeof(int) * len);

	//释放pTemp
	delete[] pTemp;
}

void print(int* arr, int len)
{
	for (int i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}

猜你喜欢

转载自blog.csdn.net/kdnnnd/article/details/120245052