DS--详细解析归并排序,快速排序,C语言编写(VS2013)

一,归并排序

归并排序是一种通过递归来对一个数组里的数据进行拆分,然后在分割后从下往上进行有序合并的过程
(每一次合并都进行一次排序)
归并排序
归并排序的程序如下:

先递归,后打印根节点,归并排序的本质就是二叉树的后序遍历
每一次递归,在回递归的过程中都会对数据进行一次有序排列合并
最后的得到一个有序的数组
在这里插入图片描述
在这里插入图片描述
程序如下:

void dealMergeSort(int *arr, int*tmp, int start, int end)//时间复杂度:nlogn
{
	if (start >= end)//到了叶子
	{
		return;
	}
	int mid = (start + end) / 2;//分左右子树
	dealMergeSort(arr, tmp, start, mid);//遍历左子树
	dealMergeSort(arr, tmp, mid + 1, end);//遍历右子树
	//其实这是一个二叉树的后序遍历
	int a = start;
	int b = mid + 1;
	int c = a;
	int i;
	for (; a <= mid && b <= end;c++)//此时的mid左右两边已经有序,当a,b中某一个元素完全拷贝到了c,循环跳出
	{
		if (arr[a] >= arr[b])//保证mid左边的值都比右边的小
		{
			tmp[c] = arr[b];
			b++;
		}
		else
		{
			tmp[c] = arr[a];
			a++;
		}
	}
	for (; a <= mid; a++,c++)//如果是b完全拷贝到了c,就将a剩余部分拷贝到c
	{
		tmp[c] = arr[a];
	}
	for (; b <= end; b++, c++)//如果是a完全拷贝到了c,就将b剩余部分拷贝到c
	{
		tmp[c] = arr[b];
	}
	for (i = 0; i <= end; i++)//tmp只是一个临时变量,需要将tmp中的值拷贝到arr中
	{
		arr[i] = tmp[i];
	}
}

void mergeSort(int *arr, int n)
{
	int *tmp = (int *)malloc(n*sizeof(int));
	dealMergeSort(arr, tmp, 0, n - 1);
	free(tmp);
}
void printArray(int*arr, int n)//打印函数
{
	int i = 0;
	for (; i < n; i++)
	{
		printf(" %d ", arr[i]);
	}
	putchar('\n');
}
int main()
{
	int a[] = { 2, 4, 5, 23, 54, 14, 78 };
	mergeSort(a, ARRSIZE(a));
	printArray(a, ARRSIZE(a));
	system("pause");
	return 0;
}

二,快速排序

方法一:通过前后指针两个指针来进行排序
详情如下图
在这里插入图片描述

void swapArgs(int *a, int *b)
{
	int tmp=0;
	tmp = *a;
	*a = *b;
	*b = tmp;
}
void dealQSort(int *arr, int start, int end)//相当于一个二叉树的前序
{
	if (start >= end)
	{
		return;
	}
	int flag = 1;
	int i = start;
	int j = end;
	while(i<j)//当start和end交换的时候,就退出
	{
		if (arr[i] > arr[j])//如果前面的大于后面的就进行交换
		{
			swapArgs(&arr[i], &arr[j]);
			flag = !flag;
		}
		if (flag)//如果交换成功,就将j前移
		{
			j--;
		}
		else//否则就i后移
		{
			i++;
		}
	}
	dealQSort(arr, start, i-1);//对左子树进行排序
	dealQSort(arr, i + 1, end);//对右子树进行排序
}
void quickSort(int *arr, int n)
{
	dealQSort(arr, 0, n - 1);
}

方法二:挖坑法
程序详解
在这里插入图片描述
所谓的挖坑法就是选一个数字存入tmp中,然后将数组中的每一个值与tmp进行比较,比tmp小的放到左边,比tmp大的放到右边,最后将tmp放到中间,经过递归,一直进行这一操作,最终得到一个有序的数组

void dealquickSort(int *arr, int start, int end)
{
	if (start >= end)
	{
		return;
	}
	int flag = 1;
	int i = start;
	int j = end;
	int tmp = arr[start];
	while (i<j)//当start和end交换的时候,就退出
	{
		if (flag&&tmp > arr[j])
		{
			arr[i] = arr[j];
			flag = !flag;
		}
		if (!flag&&tmp < arr[i])
		{
			arr[j] = arr[i];
			flag = !flag;
		}
		flag ? j-- : i++;
	}
	arr[i] = tmp;
	dealquickSort(arr, start, i - 1);//对左子树进行排序
	dealquickSort(arr, i + 1, end);//对右子树进行排序
}
void quickSort(int *arr, int n)
{
	dealquickSort(arr, 0, n - 1);
}
void printArray(int*arr, int n)
{
	int i = 0;
	for (; i < n; i++)
	{
		printf(" %d ", arr[i]);
	}
	putchar('\n');
}
int main()
{
	int a[] = { 2, 4, 5, 23, 54, 14, 78 };
	quickSort(a, ARRSIZE(a));
	printArray(a, ARRSIZE(a));

	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44930562/article/details/100145731
今日推荐