数据结构与算法——排序算法之快速排序

数据结构与算法——排序算法之快速排序

  • 快速排序定义

    快速排序由C. A. R. Hoare在1962年提出通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

  • 快速排序的优势

    桶排序浪费空间严重,而冒泡排序解决了这一问题,但是在算法的执行效率上大打折扣。快速排序既解决了空间浪费问题,又使运算速度大幅提高,可谓一举双得。

  • 自然语言描述(以降序为例)

    • Step1: 选定一个最左或最右为基准数(本例选择最左)
    • Step2: 定义两个标志变量,分别指向数据的两边有(以下简称左标和右标)。
    • Step3: 右标开始向左移动,直到遇到小于基准数的数时停下来。
    • Step4: 左标开始向右移动,直到遇到大于基准数的数时停下来。
    • Step5: 将左右两标所指数字互换,重复第三四五步,直到左右两标指向同一数字,这三个步骤称为一趟。
    • Step6 : 两标指向的同一数字与基准数互换完成快排。

- 代码实现:

  [ 一 ]  C语言实现
#include <stdio.h>
int a[101],n;//定义全局变量,这两个变量需要在子函数中使用
void quicksort(int left, int right); 
int main()
{
	int i,j;
	//读入数据
	scanf("%d",&n);
	for(i=1; i<=n; i++)
		scanf("%d",&a[i]);
	quicksort(1,n);//快速排序调用
	
	//输出排序后的结果
	for(i=1; i<=n; i++)
		printf("%d ",a[i]);
		
	return 0; 
}
void quicksort(int left, int right)
{
	int i,j,t,temp;
	if(left > right)
		return;
	
	temp = a[left];//temp中存的就是基准数
	i = left;
	j = right;
	while(i != j)
	{
		//顺序很重要要先从右往左找
		while(a[j] >= temp && i<j)
			j--;
		//再从左往右找	
		while(a[i] <= temp && i<j) 
			i++;
		//交换两个数在数组中的位置 
		if(i<j) //当哨兵i和哨兵j没有相遇时
		{
			t = a[i];
			a[i] = a[j];
			a[j] =t;
		}
		 
	}
	//最终将基准数归位
	 a[left] = a[i];
	 a[i] = temp;
	 
	quicksort(left,i-1);//继续处理左边的,这里是一个递归的过程 
	 quicksort(i+1,right);//继续处理右边的,这里是一个递归的过程 
	
	
}	
  • [ 二 ] java实现

public static int partition(int []array,int lo,int hi){
        //固定的切分方式
        int key=array[lo];
        while(lo<hi){
            while(array[hi]>=key&&hi>lo){//从后半部分向前扫描
                hi--;
            }
            array[lo]=array[hi];
            while(array[lo]<=key&&hi>lo){从前半部分向后扫描
                lo++;
            }
            array[hi]=array[lo];
        }
        array[hi]=key;
        return hi;
    }
    
    public static void sort(int[] array,int lo ,int hi){
        if(lo>=hi){
            return ;
        }
        int index=partition(array,lo,hi);
        sort(array,lo,index-1);
        sort(array,index+1,hi); 
    }
  • 复杂度分析:

    1. 快速排序每次交换都是跳跃式的而不像冒泡每次都是相邻交换,交换距离得到拓展,快排最坏时间复杂度为O(N^2), 与冒泡的一样,因为快排比较与冒泡来说的优势就是交换距离扩展,最差情况下优势没了,自然就与之一样了。
    2. 快排的平均复杂度为O(NlogN)。
  • 算法思想(分而治之):
    1. 古代君王统治大片国土常用分治法,如我们所知的分封制,郡县制等等。采用分治法的原因很简单,1. 国土面积大,2.君王自身精力有限。
    2. 同样我们面对规模较为复杂的问题时,可以借助于将其分为等价的规模较小的几个模块而解决,分而治之与软件设计的模块化思想有些类似,较大问题的解决都是基于较小问题的解决借助于递归而解决的。

猜你喜欢

转载自blog.csdn.net/weixin_42448798/article/details/85045667