• 快速排序


    快速排序是一种分治的排序算法。 它的工作原理是将一个数组分成两部分,
    通过切分实现某一部分总小于另一数组,然后分别独立排序。

    切分

    实现1
    1. 一般策略是先随意地选取 a[lo] 作为切分元素,即那个会被排定的元素,然后我们
    2. 从数组的左端开始向右扫描直到找到一个大于等于它的元素,
    3. 再从数组的右端开始向左扫描直到找到一个小于等于它的元素。
    4. 交换它们的位置
    5. 递归1-4,当两个指针相遇时,我们就可以保证左指针 i 的左侧元素都不大于切分元素,右指针 j 的右侧元素都不小于切分元素。
    6. 我们只需要将切分元素 a[lo] 和左子数组最右侧的元素(a[j])交换然后返回 j 即可。
      注:此时a[i]找到大于a[lo]的元素,a[j]找到小于a[lo]的元素,所以a[lo]只能和a[j]交换
    public static int partition(Comparable[] a, int lo, int hi) {
    	int i = lo, j = hi + 1;
    	Comparable v = a[lo];
    	while (true) {
    		while (less(a[++i], v)) {//找一个 比V大的数的index  i
    			if (i == hi) {
    				break;
    			}
    		}
    		while (less(v, a[--j])) {//找一个比v小的数的index   j
    			if (j == lo) {
    				break;
    			}
    
    		}
    		if (i >= j) {//如果i的 index 在j 的右边就不交换
    			break;
    		}
    		exch(a, i, j);
    	}
    	exch(a, lo, j);
    	return j;
    }
    
    实现2
    private int Partition(Comparable data[], int start, int end) {
    	//生成start 到 end 结尾的随机数[start,end]
    	int index = RandomInRange(start, end);
    	swap(data, index, end);
    	int small = start - 1;//相当于标记你应该存在什么位置
    	for (index = start; index < end; index++) {
    		if (less(data, index, end)) {
    			small++;
    			//小老弟前面怎么不来,滚后面去
    			if (index != small) {
    				swap(data, small, index);
    			}
    		}
    	}
    	small++;
    	swap(data, small, end);
    	return small;
    }
    /**
     * 生成start 到 end 结尾的随机数
     * [start,end]
     */
    private int RandomInRange(int start, int end) {
    	return random.nextInt(end - start + 1) + start;
    }
    

    最坏情况

    如果数组有序的话,此时是最坏情况,因为每次递归右子数组规模只比原数组减一,这样递归次数就会很多

    最好情况

    每次选到一个中轴元素刚好位于中间


    public class Quick {
        public static void sort(Comparable[] a) {
    		StdRandom.shuffle(a);   // 消除对输入的依赖
            sort(a, 0, a.length - 1);
        }
    
        private static void sort(Comparable[] a, int lo, int hi) { 
            if (hi <= lo) return;
            int j = partition(a, lo, hi); // 切分
            sort(a, lo, j-1);			  // 左半部分排序
            sort(a, j+1, hi);			  // 右半部分排序
        }
    }
    

    特点

    快排之所以块,就是因为它高度优化的内部循环(分割),它既不像归并那样需要辅助数组来回复制元素,也不像堆排序无法利用缓存并且有许多无用的比较,并且最坏情况可以采用一些方法避免

  • 相关阅读:
    POX flow_stats2.py analysis by uestc_gremount
    C#基础知识点
    C++学了这么多年,你仍不知道的事
    VC7 HTML Dialog开发实例讲解
    VC与JavaScript交互(四) --- WebBrowser或CHtmlView中轻松屏蔽脚本错误(JavaScript)
    VC与JavaScript交互(三) --- CWebPage类调用javascript函数(给js函数传参,并取得返回值)
    VC与JavaScript交互(二) --- 调用JS函数
    VC与JavaScript交互(一) --- 如何实现
    动态链接库(VC_Win32)
    wcscpy wcscpy_s strcpy strcpy_s的区别
  • 原文地址:https://www.cnblogs.com/aiguozou/p/11408841.html
Copyright © 2020-2023  润新知