其他分享
首页 > 其他分享> > 看正月点灯笼老师的笔记—快速排序

看正月点灯笼老师的笔记—快速排序

作者:互联网

 

这是快排的代码。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define N 1086
int a[N];
int partition(int L, int R)
{
	int i = L, j = L;
	int p = a[R];
	for (; i <= R; i++)
	{
		if (a[i] < p)
		{
			int t = a[i];
			a[i] = a[j];
			a[j] = t;
			j++;
		}
	}
	a[R] = a[j];
	a[j] = p;

	return j;
}
void quick_sort(int L, int R)
{
	if (L < R)
	{
		int m = partition(L, R);
		quick_sort(L, m - 1);
		quick_sort(m + 1, R);
	}
}
int main(void)
{
	int n;
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &a[i]);
	}
	quick_sort(0, n - 1);
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}puts("");

	system("pause");
	return 0;
}

  

我在这主要想讲一下 patition 这个函数。其中运用了一个十分巧妙的算法,由于我不知道这个算法叫什么名字,

但我愿称之为 区间移动

1,首先 定义 i 指向 区间最后一个元素的位置, j 指向 区间的第一个元素的位置

2,将 i 和 j 初始化为 0,此时区间并无元素,所以需要 i 遍历一遍数组,把满足条件的数组添加到 i 和 j 之间,

3,怎么添加元素到区间里面呢?

原来 是通过 i 去试探元素是否符合条件,若符合条件,则 i 继续试探下一个元素, j 留下来指向区间的第一个元素,这样 i 和 j 就错开了

                                                     若符合条件 , 则把 i 指向的元素和 j 指向的元素交换位置,这样就把整个区间向后移动一位了,然后  i 继续试探下一个元素

                                                       不过这样原本区间元素的首尾的位置就交换了一下,所以最后得到的区间里的元素位置相对于原数组的位置是不同。

稍微总结一下,不管是否满足条件 i 都是要试探下一个元素的,所以 i 始终是加 1 的。真正改变区间长度的是 j ,若 j 加 1 使区间后移,若 j 不变,则区间扩大。

4,最后一个问题,在 partiiton 这个函数的区间的移动条件是 数组元素小于最后一个元素(其实应该反过来说是大于等于,不过代码写出来的判定条件就是这个),

那么问题来了,当 i 移动到数组的最后一个元素时,这个元素确实满足区间的条件,应该呆在区间里,所以循环就此结束。

这没有问题,有问题的是快速排序,因为快排需要的不是左边元素全部小于右边的,而是数组中间有一个元素,左边全部小于这个元素,右边全部大于这个元素,正月老师称之为 支点,

而 partition 中,数组最后一个元素就一直被用做支点,作为判断条件,

所以在函数最后还要交换一下区间头尾,即 a[i]和 a[j] ,

使数组分隔开,做到 partition.

 

标签:partition,指向,int,元素,笔记,灯笼,数组,区间,排序
来源: https://www.cnblogs.com/asdfknjhu/p/12374264.html