归并排序

归并排序

1.思路

通过不断的划分区域,使其每个区域独自有序,为后续的合并埋下伏笔。由于两个区域是有序的,合并的时候就会降低排序的时间复杂度。

2.代码

2.1递归思想

#include<stdio.h>
#include<stdlib.h>

int n;
int* a;

void init() {
	printf("请输入n:");
	scanf("%d", &n);
	a = (int*)malloc(sizeof(int) * n);
	for (int i = 0; i < n; i++)
		scanf("%d", a + i);
}

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

void merge(int* temp, int left, int mid, int right) {
	int l_pos = left;
	int r_pos = mid + 1;
	int pos = l_pos;
	while (l_pos <= mid && r_pos <= right) {
		if (a[l_pos] < a[r_pos])
			temp[pos++] = a[l_pos++];
		else
			temp[pos++] = a[r_pos++];
	}
	while (l_pos <= mid)
		temp[pos++] = a[l_pos++];
	while(r_pos <= right)
		temp[pos++] = a[r_pos++];
	while (left <= right) {
		a[left] = temp[left];
		left++;
	}
}

void Sort(int* temp, int left, int right) {
	if (left < right) {
		int mid = (left + right) / 2;
		Sort(temp,left,mid);
		Sort(temp, mid + 1, right);
		merge(temp,left,mid,right);
	}
}

void mergeSort() {
	int* temp = (int*)malloc(sizeof(int) * n);
	if (temp) {
		Sort(temp, 0, n - 1);
		free(temp);
	}
	else
		printf("error:failed to allocate the memory");
}

int main() {
	init();
	mergeSort();
	print();
	free(a);
	return 0;
}

2.2迭代思想

void mergeSort() {
	for (int curr_size = 1; curr_size <= n - 1; curr_size = 2 * curr_size) {
		for (int left = 0; left < n - 1; left += 2 * curr_size) {
            //找到每一次的中间位置和左端结束位置
			int mid = min(left + curr_size - 1, n - 1);
			int right = min(left + 2 * curr_size - 1, n - 1);
			int l_pos = left;
			int r_pos = mid + 1;
			int pos = left;
			while (l_pos <= mid && r_pos <= right) {
				if (a[l_pos] < a[r_pos]) temp[pos++] = a[l_pos++];
				else temp[pos++] = a[r_pos++];
			}
			while(l_pos <= mid) temp[pos++] = a[l_pos++];
			while(r_pos <= right) temp[pos++] = a[r_pos++];
			for (int i = left; i <= right; i++)
				a[i] = temp[i];
		}
	}
}
posted @ 2022-10-14 21:58  彭乐祥  阅读(17)  评论(0编辑  收藏  举报