• 快速排序


    算法思想

    1. 从数列中挑出一个元素,称为"基准"(pivot),
    2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
    3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

    动画演示:

    实现

    C++

    int partition(vector<int> &a, int left, int right)
    {
    	int pivotPos = left;      //记录轴值位置
    	int pivot = a[left];      //取最左边的值作为轴值
    	left++;                  //避开轴值
    	while (left < right)       //从左右两边各自扫描数组,左边遇到比轴值大的就停下,右边遇到比轴值小的就停下,交换。继续。。。
    	{
    		while (a[left] < pivot && left < right)
    			left++;
    		while (a[right] > pivot && left < right)
    			right--;
    		swap(a[left], a[right]);
    	}
    	if (a[right] < a[pivotPos])
    	{
    		swap(a[right], a[pivotPos]);
    		return right;
    	}
    	else
    	{
    		swap(a[right - 1], a[pivotPos]);
    		return right - 1;
    	}
    }
    
    void quickSortHelp(vector<int> &a, int left, int right)
    {
    	if (left >= right)
    		return;
    
    	int k = partition(a, left, right);  //通过partition将数组按比轴值大小分别放到轴值左右两边,返回最后轴值的位置k。
    
    	quickSortHelp(a, left, k - 1);
    	quickSortHelp(a, k + 1, right);
    }
    
    
    void quickSort(vector<int> &a)
    {
    	int len = a.size();
    	quickSortHelp(a, 0, len - 1);
    }
    

    python

    def quickSort(alist):
       quickSortHelper(alist,0,len(alist)-1)
    
    def quickSortHelper(alist,first,last):
       if first<last:
    
           splitpoint = partition(alist,first,last)
    
           quickSortHelper(alist,first,splitpoint-1)
           quickSortHelper(alist,splitpoint+1,last)
    
    def partition(alist,first,last):
       pivotvalue = alist[first]
       
       leftmark = first+1
       rightmark = last
    
       done = False
       while not done:
    
           while leftmark <= rightmark and alist[leftmark] <= pivotvalue:
               leftmark = leftmark + 1
    
           while alist[rightmark] >= pivotvalue and rightmark >= leftmark:
               rightmark = rightmark -1
    
           if rightmark < leftmark:
               done = True
           else:
               temp = alist[leftmark]
               alist[leftmark] = alist[rightmark]
               alist[rightmark] = temp
    
       temp = alist[first]
       alist[first] = alist[rightmark]
       alist[rightmark] = temp
       
       return rightmark
    

    总结

    稳定性:
    快速排序并不是稳定的,这是因为我们无法保证相等的数据按顺序被扫描到和按顺序存放。

    适用场景:
    快速排序在大多数情况下都是适用的,尤其在数据量大的时候性能优越性更加明显。但是在必要的时候,需要考虑下优化以提高其在最坏情况下的性能。

    复杂度:
    (O(N * log N))

  • 相关阅读:
    20155303 实验五 网络编程与安全
    20155303 2016-2017-2 《Java程序设计》课程总结
    20155303 实验四 Android程序设计
    《Java 程序设计》课堂实践项目 课后学习总结
    20155303 实验三 敏捷开发与XP实践
    20155303 2016-2017-2 《Java程序设计》第十周学习总结
    Java第七次作业--图形用户界面
    Java第六次作业--异常处理和Java类集
    Java第五次作业--面向对象高级特性(抽象类和接口)
    Java第四次作业--面向对象高级特性(继承和多态)
  • 原文地址:https://www.cnblogs.com/chay/p/10673564.html
Copyright © 2020-2023  润新知