二路归并排序(迭代)——ANSI C实现

typedef int ElementType;


 

/*
 * 将两个数组有序归并到一个数组中
 *
 * 输入参数1:第一个数组
 * 输入参数2:第一个数组的尺寸
 * 输入参数3:第二个数组
 * 输入参数4:第二个数组的尺寸
 *
 * 返回类型:有序归并后的新数组
 *
 * */
void MergeArray(ElementType *arr1, int size1, ElementType *arr2, int size2, ElementType *newArr) {
	// 检查输入参数
	if (newArr == NULL) {
		return;
	}
	if ((arr1 == NULL || size1 == 0) && (arr2 == NULL || size2 == 0)) {
		return;
	}
	if (arr1 == NULL || size1 == 0) {
		for (int index = 0; index < size2; index++)
			newArr[index] = arr2[index];
		return;
	}
	if (arr2 == NULL || size2 == 0) {
		for (int index = 0; index < size1; index++)
			newArr[index] = arr1[index];
		return;
	}

	// 比较arr1与arr2中每个元素的大小,依次插入到newArr中
	int i = 0, j = 0, k = 0;
	while (i < size1 && j < size2) {
		if (arr1[i] <= arr2[j]) {
			newArr[k] = arr1[i];
			i++;
			k++;
		}

		if (arr1[i] > arr2[j]) {
			newArr[k] = arr2[j];
			j++;
			k++;
		}
	}

	// 插入arr1中的剩余元素
	while (i < size1) {
		newArr[k] = arr1[i];
		i++;
		k++;
	}

	// 插入arr2中的剩余元素
	while (j < size2) {
		newArr[k] = arr2[j];
		j++;
		k++;
	}
}


 

// 填充符号
#define FILLER_CHAR -1
ElementType *Sort(ElementType *arr, int size) {
	// 检查参数,若arr为NULL或size为0,则说明是空表,返回NULL
	if (arr == NULL || size <= 0)
		return NULL;

	// 求需要迭代的轮数,以及大于size,且是2的整数次幂的整数
	int round = 0, compSize = 1;
	while (compSize < size) {
		round++;
		compSize *= 2;
	}

	// 为辅助数组申请空间
	ElementType *assist1 = (ElementType *) malloc(compSize * sizeof(ElementType));
	ElementType *assist2 = (ElementType *) malloc(compSize * sizeof(ElementType));

	// 将arr内的元素拷贝到assist1中,多于空位用填充符号补齐
	for (int index = 0; index < compSize; index++) {
		if (index < size)
			assist1[index] = arr[index];
		else
			assist1[index] = FILLER_CHAR;
	}

	// 进行round轮二路归并排序
	int subSize = 1;
	int *temp = NULL;
	for (int k = 1; k <= round; k++) {
		for (int i = 0; i < compSize; i += 2 * subSize) {
			MergeArray(assist1 + i, subSize, assist1 + i + subSize, subSize, assist2 + i);
		}

		// 求出下一轮归并时,每个子序列的大小
		subSize *= 2;

		// 交换assist1与assist2
		temp = assist1;
		assist1 = assist2;
		assist2 = temp;
	}

	// 将排序后的assist1中的元素拷贝回arr
	for (int i = size - 1, j = compSize - 1; i >= 0; i--, j--)
		arr[i] = assist1[j];

	return arr;
}


 

int main() {

	int size = 10;
	int max = 300;
	int *array = GetRandomArray(size, max);
	printf("Original ");
	PrintArray(array, size);
	Sort(array, size);
	printf("Sorted   ");
	PrintArray(array, size);

	return 0;
}


 

你可能感兴趣的:(二路归并排序(迭代)——ANSI C实现)