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


     这是快排的代码。

    #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 指向的元素交换位置,然后再 j++ , 这样就把整个区间向后移动一位了,然后  i 继续试探下一个元素

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

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

    4,最后一个问题,在 partiiton 这个函数的区间里面放的是大于等于数组最后一个元素的元素,所以它的移动条件是 数组元素小于最后一个元素(因为要不符合才移动),

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

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

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

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

    使数组分隔开,做到 partition.

    ========== ========= ======== ======= ====== ===== ==== === == =

      菩萨蛮  韦庄 唐

    如今却忆江南乐,当时年少春衫薄。骑马倚斜桥,满楼红袖招。
    翠屏金屈曲,醉入花丛宿。此度见花枝,白头誓不归。 
  • 相关阅读:
    Codeforces Round #609 (Div. 2)
    Educational Codeforces Round 78 (Rated for Div. 2)
    Codeforces
    crontab
    C6 C7的开机启动流程
    平均负载压力测试
    ps 和 top
    if判断
    使用3种协议搭建本地yum仓库
    linux rpm包
  • 原文地址:https://www.cnblogs.com/asdfknjhu/p/12374264.html
Copyright © 2020-2023  润新知