快速排序(C/java)

算法思想:从待排序的序列中选取一个元素(通常情况下选取第一个元素)作为枢轴,其关键字设为base,然后将其余小于base的元素移到前面,将大于等于base的元素移到后面,结果将待排序的元素序列分成了两个子序列,最后将关键字base插入分界线的位置,此过程被称为一趟快速排序。

     对于分割后的子序列继续按上面的原则进行分割,直到所有子序列的长度不超过1为止,此时,待排序的记录序列变成了一个有序序列。

举例:3 5 1 2 10 4 7 8 9 6,对于一个长度为10的无序序列选择第一个元素3作为base。

从右到左寻找小于3的元素找到a[3]=2<3;将2移动到空单元a[0]处。

                       _    5   1   2   10   4   7  8   9   6——>2   5   1    _    10   4   7   8   9   6

从左到右寻找大于3 的元素找到a[1]=5>3;将5移动到空单元a[3]处。

                       2    5   1   _   10   4   7   8   9   6——>2   _   1     10   4   7   8   9   6

然后再从左到右寻找小于3的元素找到a[2]=1<3,将1移动到空单元a[1]处。

                       2   _   1   5  10   4   7   8   9   6——>2     _   5   10   4   7   8   9   6

最后将base值放在空单元a[2]处得到第一次快速排序结果:2   1   3   5   10  4   7   8   9   6

核心代码:

void quickSort(int a[],int begin,int end)
{
  if(begin<end)
  {
  	int base=a[begin];//选择基准为数组第一个元素 
  	int i=begin;
  	int j=end;
  	while(i<j){
  		while(i<j&&a[j]>base)//序列从右到左寻找小于base的元素 
  		 j--;
  		if(i<j){//找到小于base的元素,将其赋给空单元a[i] 
  			a[i]=a[j];
  			i++;
		  }
		while(i<j&&a[i]<base)//从左到右寻找大于base的元素 
		    i++;
		if(i<j)//找到大于或等于base的元素,将其送入空单元a[j] 
		{
			a[j]=a[i];
			j--;
		}
	  }
	a[i]=base;
	//递归 
	quickSort(a,begin,i-1);//base左侧表进行上述快速排序 
	quickSort(a,i+1,end);//base右侧表进行上述快速排序 
  }
		
}

最好情况:每一趟将序列一份为二,正好在序列中间,将序列分为两个大小相等的子序列,类似于折半查找,此时的时间复杂度为O(nlog2n);

最坏情况:已经排好序,第一趟经过n-1次比较,第一个元素定在原位置,左边的子序列为空序列,右边子序列为n-1个元素;第二趟n-1个元素经过n-2次比较,第二个元素定在原位置,左边子序列为空序列,右边子序列为n-2;依次类推,共需要进行n-1次排序,比较次数:

             \sum_{i=1}^{n-1}(n-i)=(n-1)+(n-2)+...+1=n(n-1)/2\approx n^2/2

时间复杂度为O(n^2);

快速排序递归算法的执行过程对应一棵二叉树,理想情况下是一棵完全二叉树,递归工作栈的大小与递归调用二叉树深度对应,平均空间复杂度为O(log2n)

选择基准法:

1.为了避免枢轴元素为最大或最小值,可以采用三元素值取中间值的办法,如{47,78,99,25,60},从47,99,60中选择60。

2.随机选取某个元素作为枢轴元素。

快速排序是一种不稳定排序

C语言可运行代码:

#include<stdio.h>
void printArray(int a[],int n)
{
	for(int i=0;i<n;i++)
	   printf("%-4d",a[i]);
	printf("\n");
}
void quickSort(int a[],int begin,int end)
{
  if(begin<end)
  {
  	int base=a[begin];//选择基准为数组第一个元素 
  	int i=begin;
  	int j=end;
  	while(i<j){
  		while(i<j&&a[j]>base)//序列从右到左寻找小于base的元素 
  		 j--;
  		if(i<j){//找到小于base的元素,将其赋给空单元a[i] 
  			a[i]=a[j];
  			i++;
		  }
		while(i<j&&a[i]<base)//从左到右寻找大于base的元素 
		    i++;
		if(i<j)//找到大于或等于base的元素,将其送入空单元a[j] 
		{
			a[j]=a[i];
			j--;
		}
	  }
	a[i]=base;
	//递归 
	quickSort(a,begin,i-1);//base左侧表进行上述快速排序 
	quickSort(a,i+1,end);//base右侧表进行上述快速排序 
  }
		
}
int main(){
	int a[10];
	printf("please enter 10 numbers:\n");
	for(int i=0;i<10;i++)
	   scanf("%d",&a[i]);
	printf("the array before sort:\n");
	printArray(a,10);
       quickSort(a,0,9);
	printf("the array after sort:\n");
       printArray(a,10);
	return 0;	   
}

运行结果:

java可运行代码: 

package one;
import java.util.Scanner;
public class quickSort {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int[] a = new int[10];
        System.out.println("please enter 10 numbers");
        for (int i = 0; i < a.length; i++)
            a[i] = input.nextInt();
        System.out.println("the array before sort:");
        print(a);
        System.out.println();
        sort(a,0,a.length-1);
        System.out.println("the array after sort:");
        print(a);
    }

    public static void print(int[] a) {
        for (int i = 0; i < a.length; i++)
            System.out.printf("%-4d", a[i]);
    }

    public static void sort(int[] a, int begin, int end) {
        if(begin<end)
        {
            int base=a[begin];//选择基准为数组第一个元素
            int i=begin;
            int j=end;
            while(i<j){
                while(i<j&&a[j]>base)//序列从右到左寻找小于base的元素
                    j--;
                if(i<j){//找到小于base的元素,将其赋给空单元a[i]
                    a[i]=a[j];
                    i++;
                }
                while(i<j&&a[i]<base)//从左到右寻找大于base的元素
                    i++;
                if(i<j)//找到大于或等于base的元素,将其送入空单元a[j]
                {
                    a[j]=a[i];
                    j--;
                }
            }
            a[i]=base;
            //递归
            sort(a,begin,i-1);//base左侧表进行上述快速排序
            sort(a,i+1,end);//base右侧表进行上述快速排序
        }
    }
}

运行结果:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值