快速排序算法原理


1.快速排序算法是什么?
想必大家都学过和用过冒泡排序吧!这应该是大家成为程序员道路上学的第一个算法哦,那么我们的快速排序算法其实是在冒泡排序的基础上的一个改进,快速排序算法是利用一趟快速排序,一趟快排一般都是取第一个数作为准基数进行排序,将一串数据分成两个部分,

 

第一部分都比准基数小,第二部分都比准基数大,如:(-------第一部分------准基数------第二部分),也就这样以准基数分成了两个部分,接下来这两个部分继续使用一趟快排(可以用递归的方法),以此类推,最后数据显示是从小到大的排列顺序,

 

2.一趟快速排序是什么?

 

 

我们我们先建立一组数据:

 

12

30

5

16

5

1

20

数据

0

1

2

3

4

5

6

下标

1.根据一趟快排的规则,我们先定下一个准基数,通常准基数都是数据的第一位也就是这里的数字12

 

2.然后一趟快排是先从下标6向左进行和准基数(12)的比较,比较完一个后,然后再从下标0向右进行和准基数(12)的比较

 

3.我们进行比较的规则和操作是:从下标6向左进行和准基数(12)的比较,只要遇到的数据小于准基数(12的时候我们就将这个数和准基数(12)进行替换,然后再执行从下标0向右进行和准基数(12)的比较

 

如:我们从下标6向左进行和准基数(12)的比较,20>12,不满足一趟快排的规则,寻找下一位,1<12,所以我们将下标0的值和下标5的值进行替换替换后的结果为:

1

30

5

16

5

12

20

数据

0

1

2

3

4

5

6

下标

 

4. 执行完上一步之后,我们再从下标0向右进行和准基数(12)的比较,这里的规则是只要遇到的数据大于准基数(12的时候我们就将这个数和准基数(12)进行替换,和上面一步恰恰相反

 

如:我们再从下标0向右进行和准基数(12)的比较,30>12,所以我们将下标1的值和下标5的值进行替换

1

12

5

16

5

30

20

数据

0

1

2

3

4

5

6

下标

 

5.从左到右查找和从右到左的查找,都是通过下标来查找的,只要它们两者下标不相遇就可以一直进行排序,直到相遇后第一次一趟快排结束,不过,总有一次会相遇的。好啦,执行完上一步之后,基本的套路也就生成了,你们可以试一下继续执行3,4步骤吧!

 

5. 第一次一趟快排结束显示结果为:

1

5

5

12

16

30

20

数据

0

1

2

3

4

5

6

下标

 

6. 从上面第一次一趟快排结果我们可以看出从准基数那里将数据分成的两个部分,前面那一部分,1,5,5,都比准基数要小,后面的16,30,20,则比准基数要大。但是这还不算完,我们明显的看到排序并非从小到大。所以说我们需要把这整一条数据分成1,5,5和16,30,20这两个条数据再次进行一趟快排(递归),以此类推,直到排出一条规矩的数据为止

 

最后结果为:

1

5

5

12

16

20

30

数据

0

1

2

3

4

5

6

下标

 

代码实现如下:

 

package com.test;

public class temps {

	
	public static void main(String[] args) {
	    int[] a = {12,20,5,16,15,1,30,45,23,9,4,4};
        int min = 0;
        int max = a.length-1;
        sort(a, min, max);
        for (int i : a) {
			System.out.println(i);
		}
	}
	
	
	/*
	 * 首先需要一个数组存放所有的数据
	 * 定一个开始位置和一个结束为止
	 * 选择一个数作为准基数
	 */
	public static void sort(int a[],int min,int max) {
		int key=a[min];//准基数
        int start=min; //开始位置
        int end =max;//结束位置
        
        while(end>start) {  //循环条件是否数值交叉
        	//从后开始往前查找
        	while(end>start&&a[end]>=key) {
        		//如果找到的值大于基数值,那么继续往下找,end--
        		end--;
        	}
        		//如果找到的值小于基数值,那么进行值交换
        		if(a[end]<key) {
        			int i=a[end];
        			a[end]=a[start];
        			a[start]=i;
        		
        	}
        	
        	//从前往后找
        	while(end>start&&a[start]<=key) {
        		//如果找到的值小于基数值,那么继续往下找,start++
        		start++;
        	}
        		//如果找到的值大于基数值,那么进行值交换
        		if(a[start]>key) {
        			int i=a[start];
        			a[start]=a[end];
        			a[end]=i;
        		
        	}
        }
		
        
      //这部分的数据都是小于准基数,通过递归在进行一趟快排
        if(start>min) {
        	 sort(a, min, start-1);  //开始位置为第一位,结束位置为关键索引-1
        }
        
        if(end<max) {
        	 sort(a, end+1, max);  //开始位置为关键索引+1,结束位置最后一位
        }
        
        
		
		
	}
	
	
	
}

 

运行结果:

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值