快速排序算法的理解


快速排序算法:

大体的思路是这样的:

类似一个挖坑、填坑的过程。

假设要把数组从小到大排序。

1)第一个坑iStart,以第一个数为准,值为A,把数组中从leftrigth的位置,大于A的放右边,小于A的放A的左边。

 

(2)先从后面开始要找到一个比A小的值,然后拿去填现在的坑iStart。最开始的坑是第一个数的位置。

填完之后又有了一个新坑iEnd。就是刚才那个比A小的值的位置。此时iStart++

 

3)从前面开始找比A大的值,然后拿去填现在的坑iEnd(这个坑就是前面步骤留下来的坑)。填完之后又有了一个新坑iStart。就是刚才那个比A大的值的位置。此时要iEnd--

 

4)重复(2)、(3),直到分好为止,返回A的现在位置。

 

(5)利用A的位置L,递归继续分组。如0L-1,L+1rigth,重复执行(1-5),直到分无可分。

 

需要注意的是:全程要要保证iStart < iEnd


快速排序的 一般的复杂度O(mlog2N)

最坏情况:变成冒泡排序,一次只能排一个。O(n2)


#include <stdio.h>
#include <stdlib.h>
#include <time.h>


typedef int arr_t;

void dump(arr_t *pArr,int len);

int Qsort(arr_t *pArr,int left,int right);

int partion(arr_t *pArr,int left,int right);

int main()
{
    int a[1000];//={  2,  5 , 2  ,26 , 14,  2,  6 , 4 , 10 , 24};
    int i = 0;
	int len = 51;
	srand( time(NULL ));
	for(i = 0;i < len ;i++)
	{
		a[i] = rand()%100;
	}

	dump(a,len);
	printf("\n*******************\n");

    Qsort(a,0,len -1);

	dump(a,len);
	
	printf("\n*******************\n");
	
	return 0;
}

//分治,把大于第一个数的全部放一边,小于的全部放另外一边
int partion(arr_t *pArr,int left,int right)
{
	arr_t tmp = pArr[left];//原始坑
	int iStart = left;
	int iEnd = right;

	if(left > right)
	{
		printf("\n END \n");
		return 0;
	}

	while(iStart < iEnd)
	{
		//小于的时候退出
		while(iEnd > iStart&&pArr[iEnd] > tmp )
		{
			iEnd--;
		}
		//此处必须iStart++,被填过的坑就不要再拿去比较
		if( iEnd > iStart)
		{
			pArr[iStart++] = pArr[iEnd];//最开始时,pArr[iStart] ,iStart指向tmp
		}
		
		//好的,现在得了一个新坑Arr[iEnd]?
		while(iEnd > iStart && pArr[iStart] < tmp )
		{
			iStart++;
		}
		//好的,填坑,此处必须iEnd--,被填过的坑就不要再拿去比较
		if( iEnd > iStart)
		{
			pArr[iEnd--] =  pArr[iStart];
		}
		//那好。现在又有了新坑就是pArr[iStart]
		//所以最后的坑是 pArr[iStart]
		printf("\n iEnd =%d   iStart=%d \n",iEnd,iStart);
	}

	pArr[iStart] = tmp;  //最后的坑 pArr[iStart]

	
	return iStart;
}

void dump(arr_t *pArr,int len)
{
	int i = 0;
	printf("\n");
	for(i = 0;i < len ;i++)
	{
		printf("  %d",pArr[i]);
	}
	printf("\n");

	return ;
}
int Qsort(arr_t *pArr,int left,int right)
{
	static int iCount = 0;
	int l = 1;//分界线
	if(left < right )
	{
		l = partion(pArr,left,right);//分界线的位置已经排好,所有要加1和减一
		Qsort(pArr,left,l -1 );
		Qsort(pArr,l+1,right);
	}
	iCount++;

	printf("\n  iCount [%d]\n",iCount);
	

	return 0;
}








运行结果:





  60  55  36  43  20  31  97  67  46  42  60  38  25  18  73  6  40  26  97  30  13  98  20  80  14  3  71  85  67  54  16  79  61  5  75  81  88  72  48  86  66  60  24  43  79  49  1  19  28  98  49


*******************


 iEnd =49   iStart=6 


 iEnd =47   iStart=7 


 iEnd =46   iStart=10 


 iEnd =45   iStart=14 


 iEnd =44   iStart=18 


 iEnd =42   iStart=21 


 iEnd =41   iStart=23 


 iEnd =40   iStart=26 


 iEnd =37   iStart=27 


 iEnd =32   iStart=28 


 iEnd =30   iStart=30 


 iEnd =27   iStart=1 


 iEnd =26   iStart=14 


 iEnd =25   iStart=23 


 iEnd =25   iStart=25 


 iEnd =23   iStart=2 


 iEnd =22   iStart=3 


 iEnd =19   iStart=4 


 iEnd =14   iStart=5 


 iEnd =9   iStart=6 


 iEnd =6   iStart=6 


 iEnd =5   iStart=5 


 iEnd =0   iStart=0 


  iCount [1]


 iEnd =2   iStart=2 


  iCount [2]


 iEnd =4   iStart=4 


  iCount [3]


  iCount [4]


  iCount [5]


  iCount [6]


  iCount [7]


  iCount [8]


  iCount [9]


 iEnd =12   iStart=8 


 iEnd =8   iStart=8 


  iCount [10]


 iEnd =23   iStart=13 


 iEnd =21   iStart=14 


 iEnd =20   iStart=18 


 iEnd =20   iStart=20 


 iEnd =18   iStart=11 


 iEnd =17   iStart=16 


 iEnd =17   iStart=17 


 iEnd =15   iStart=15 


 iEnd =13   iStart=10 


 iEnd =13   iStart=13 


 iEnd =11   iStart=11 


 iEnd =10   iStart=10 


  iCount [11]


  iCount [12]


  iCount [13]


  iCount [14]


  iCount [15]


  iCount [16]


  iCount [17]


  iCount [18]


  iCount [19]


 iEnd =19   iStart=19 


  iCount [20]


  iCount [21]


  iCount [22]


  iCount [23]


 iEnd =22   iStart=22 


  iCount [24]


 iEnd =24   iStart=24 


  iCount [25]


  iCount [26]


  iCount [27]


  iCount [28]


  iCount [29]


  iCount [30]


  iCount [31]


 iEnd =29   iStart=29 


 iEnd =27   iStart=27 


  iCount [32]


  iCount [33]


  iCount [34]


  iCount [35]


  iCount [36]


  iCount [37]


 iEnd =47   iStart=35 


 iEnd =46   iStart=36 


 iEnd =45   iStart=38 


 iEnd =43   iStart=39 


 iEnd =41   iStart=41 


 iEnd =39   iStart=33 


 iEnd =34   iStart=34 


 iEnd =33   iStart=33 


 iEnd =31   iStart=31 


  iCount [38]


  iCount [39]


  iCount [40]


  iCount [41]


  iCount [42]


 iEnd =39   iStart=38 


 iEnd =39   iStart=39 


 iEnd =35   iStart=35 


  iCount [43]


 iEnd =38   iStart=38 


 iEnd =36   iStart=36 


  iCount [44]


  iCount [45]


  iCount [46]


  iCount [47]


  iCount [48]


  iCount [49]


  iCount [50]


  iCount [51]


  iCount [52]


 iEnd =42   iStart=42 


  iCount [53]


 iEnd =49   iStart=49 


 iEnd =47   iStart=45 


 iEnd =47   iStart=47 


 iEnd =43   iStart=43 


  iCount [54]


 iEnd =45   iStart=45 


  iCount [55]


  iCount [56]


  iCount [57]


  iCount [58]


  iCount [59]


  iCount [60]


  iCount [61]


  iCount [62]


  iCount [63]


  iCount [64]


  iCount [65]


  1  3  5  6  13  14  16  18  19  20  20  24  25  26  28  30  31  36  38  40  42  43  43  46  48  49  49  54  55  60  60  60  61  66  67  67  71  72  73  75  79  79  80  81  85  86  88  97  97  98  98


*******************
-bash-3.2$ 






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值