快排之單向掃描和雙向掃描

單向掃描法的思路:

第一步首先定主元,一般設置爲數組起始位置。

然後定義兩個指針,一個是掃描指針sp,指向主元的下一個元素

一個指右側指針bigger,指向數組最後一個元素

然後sp指針開始向右掃描,如果掃描到的元素小於主元的話sp指針向後移動sp++,否則的話 此時sp指向的元素和bigger指向的元素進行交換,然後bigger向前移動bigger--。直到sp大於bigger的時候,循環結束。

最後返回主元的正確位置,這個位置就是bigger,就是主元的左側元素都比它小,右側元素都比它的位置。

public static void quickSort(int[] A,int p, int r)
	{
		if(p<r)
		{
			int q = partition(A,p,r);
			quickSort(A,p,q-1);
			quickSort(A,q+1,r);
		}
	}
	
	
	//返回主元最終的位置
	public static int partition(int[] A,int p, int r)
	{
		int pivot = A[p]; //一般設置p位置的元素爲主元
		int sp = p+1;    //掃描指針  左側指針
		int bigger = r;  //右側指針
		
		while(sp<=bigger)
		{
			if(A[sp] <=pivot)
			{
				sp++;
			}else
			{
				swap(A,sp,bigger); //交換sp和bigger位置的元素
				bigger--;
			}
		}
		
		swap(A,p,bigger);
		return bigger;
	}

雙向掃描思路:

第一步首先定主元,一般設置爲數組起始位置。

然後定義兩個指針,一個是左指針left,指向主元的下一個元素

一個右指針right,指向數組最後一個元素

 

從left開始向後掃描,找到第一個比主元的大的元素,然後right開始向前掃描,找到第一個比主元小的元素,此時交換left和right位置的元素。直到兩個指針交叉之後,結束循環。

循環結束之後,right指向的位置就是最後一個小於等於主元的位置,也就是主元應該待的位置,那麼就進行交換right和p位置的元素。此時就一輪快排結束,主元左側的元素都小於主元,主元右側的元素都大於主元。

//返回主元最終的位置
		public static int partition2(int[] A,int p, int r)
		{
			
			//優化 在p r mid之間,選擇一箇中間值做爲主元
			int midIndex = p+(r-p)/2;  //中間下標
			int midValueIndex = -1;  //中值的下標
			if(A[p] <=A[midIndex] &&A[p]>=A[r]) 
			{
				midValueIndex = p;
			}else if(A[r]<=A[midIndex] && A[r]>=A[p])
			{
				midValueIndex = r;
			}else
			{
				midValueIndex = midIndex;
			}
			
			swap(A,p,midValueIndex);
			
			int pivot = A[p]; //一般設置p位置的元素爲主元
			int left = p+1;    // 左側指針
			int right = r;  //右側指針
			
			while(left<=right)
			{
				while(left<=right && A[left] <= pivot){
					left++;
				}
				
				while(left<=right && A[right] >pivot)
				{
					right--;
				}
				
				if(left < right)
				{
					swap(A, left, right);
				}
			}
			
			swap(A, p, right);
			return right;
		
		}

	public static void swap(int[] A,int p, int r)
	{
		int swap = A[p];
		A[p] = A[r];
		A[r] = swap;
	}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章