快速排序的看书总结

1.大话数据结构中的基本排序

第一种方式:如下图,low指向第一个元素,将high 指向最后一个元素,将low指向的元素赋值给pivotkey,从high开始,如果high指向的元素大于pivotkey,就将high向左移动,知道high指向的元素小于pivotkey,此时将low指向的元素和high指向的元素交换,然后将low指向的元素向右移动,并将low指向的元素与pivotkey比较,如果low指向的元素大于pivotkey,就将low指向的元素和pivotkey交换。过程中发现,每次滑动停止,都要进行交换。交换过程中,50反复在low和high中交换,最后high和low同时指向50时,排序停止。交换过程中,pivotkey总是在high和low中交换,在high--后,pivotkey被high指向,在low++后pivotkey被low指向


代码实现:

	public int Partition(int a[],int low,int high)
	{
		int pivot = a[low];
		int temp;
		while(low<high)			//最终停止循环的条件是low==high
		{
			while(low<high&&pivot<=a[high])
			{
				high--;
			}
			temp = a[high];
			a[high] = a[low];
			a[low] = temp;
			
			while(low<high&&pivot>=a[low])
			{
				low++;
			}
			temp = a[high];
			a[high] = a[low];
			a[low] = temp;
		}
		return low;
 	}

说明:

1)最终停止的判断条件是while(low<high),停止情况都是low==high,指向a[low]的元素。

			while(low<high&&pivot<=a[high])
			{
				high--;
			}
			temp = a[high];
			a[high] = a[low];
			a[low] = temp;

2)while(low<high&&a[high]>=pivot),这边加上判断条件是为了在下面语句执行后
low和high已经指向同一个元素,这是如果没有low<high的判断条件,会继续执行下面的语句,导致错误。
			while(low<high&&pivot>=a[low])
			{
				low++;
			}
			temp = a[high];
			a[high] = a[low];
			a[low] = temp;

第二种方式:第二种方式pivotkey指向第一个元素,low指向第二个元素,high指向最后一个元素,将low指向的元素和high指向的元素都与pivotkey比较。在low指向的值小于等于pivotkey时向右滑动,在high指向的值小于等于pivotkey时向左滑动,当滑动停止时,low停止时low指向的元素大于pivotkey,high停止时,high 指向元素小于pivotkey,此时进行交换操作最后的停止条件是low>high。停止条件if(i>=j)  break;这里是为什么要等号,看一种特殊的情况。[20, 10, 40, 60, 50, 90, 100],此时pivotkey=20,而i = 1,j=1,此时i=i=1死循环,停在这边,所以这边要加等号。

代码实现:

	public int Partition(int[] a,int low,int high)
	{
		int pivotkey = a[low];
		int i = low + 1;
		int j = high;
		while(true)
		{
			while((j>low)&&a[j]>=pivotkey)
				j--;
			
			while((i<high)&&a[i]<=pivotkey)
				i++;
			
			System.out.println("i:"+i+"  "+"j:"+j);
			if(i>j)
				break;
			
			System.out.println("过程中打印:"+Arrays.toString(a));
			int temp = a[i];
			a[i] = a[j];
			a[j] = temp;
		}
		
		int temp = a[low];
		a[low] = a[j];
		a[j] = temp;	
		return j;
	}

两者的对比:下面的写法更好,上面的写法,两端的值没有比较。

private static int partition(Comparable[] a, int lo, int hi) {
    	int i = lo;
    	int j = hi + 1;
    	Comparable pivot = a[lo];
    	while(true)
    	{
    		while(a[++i].compareTo(pivot)<=0)
    		{
    			if(i==hi)
    				break;
    		}
    		while(a[--j].compareTo(pivot)>=0)
    		{
    			if(j==lo)
    				break;
    		}
    		if(i>=j)
    		{
    			break;
    		}
    		Comparable temp = a[i];
    		a[i] = a[j];
    		a[j] = temp;
    	}
    	Comparable temp = a[lo];
    	a[lo] = a[j];
    	a[j] = temp;
    	return j;
}

这里的注意点:low<high是必须要的,举个例子,当low和high都指在一起时,再次判断下面的while循环,此时如果没有low<high,那么就会再执行low++,下面的交换也会失效。

同时注意开始的while(low<high), low<high递归控制条件,low=high区间长度等于1,low<high区间长度大于1

关于停止条件

 public void Qsort(int[] a,int low,int high)
	{
		int pivot;
		if(low<high)		//递归控制条件,low=high区间长度为1,low<high区间长度大于1
		{
			pivot = Partition(a, low, high);
			Qsort(a,low,pivot-1);
			Qsort(a,pivot+1,high);
		}
	}

这边的停止条件是low<high,根据西北大学老师的讲法,递归控制条件 l ow=high,区间长度等于1,low<high区间长度大于1,当区间长度等于1时停止。


2.改进的两种方法:

 1)很简单就是三数取中,让a[low] 的值尽量不是一个很小的值

 2)改进的第二种方式,是采用替换而不是交换的方式进行操作

总结:算法第四版的思想与大话数据结构稍稍有不同,他是讲第二个数设施为i,最后一个数设置为j,让i向后滑动,j向前滑动,最后的停止条件分为两种,第一种是j<i,第二种是j=i(笔记上有示图)。同时这里滑动的时候判别条件为(i<high),与大话数据结构中的(i<j)有不同,原因还没想清楚


3在重复元素很多的情况下,三向切分的快速排序算法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值