Sorting algorithm (VI) - quick sort

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/A1344714150/article/details/88789649

Quick sort generally they can be divided into three types, namely:

① basis quick sort

② Dual quick sort

③ three-way quick sort

The following are above three quick drain sort.

Quick sort foundation

Sort ideas: firstly passed the array to be sorted, using a variable array subscript l represents a starting point, using the variable array subscript r represents the end point, then take the first array element e do intermediary, using a cyclic array elements into progressively smaller ratio e and two smaller portions than e; using the variable j is smaller than the left recording the number of elements e index (initial value l), using the inner loop variable i from l + 1 traversing to r, if Array [i] is less than e, then the array [j + 1] with the array [i] are interchangeable and j ++, or directly i ++; after the cycle, the variable j is in the lower subscript at the rear pinion ratio e that portion of the array to be sorted leftmost side elements and array [j] exchange, and finally to give l ~ e is smaller than the portion of j-1, j + 1 ~ r is smaller than the portion e. Then continues the above-described sorting operation l ~ j-1 j 1 ~ r + and the two parts until l> = end r, sort.

Code:


	//基础版快速排序法
	public static void quickSortBase(int[] array){
		__quickSortBase(array,0,array.length-1);
	}
	
	
	public static void __quickSortBase(int[] array,int l,int r){
		int temp;
		if(l>=r){
			return ;
		}

		int e = array[l];
		int j = l;//保存<e部分尾部的下标
		for(int i=l+1;i<=r;i++){//将数组分为<e和>=e两部分
			if(array[i]<e){
				temp = array[j+1];
				array[j+1] = array[i];
				array[i] = temp;
				j++;
			}
		}
		//排序完成后,将array[j]与array[l]进行交换,此时l~j-1为<e部分,j+1~r为>=e部分
		temp = array[j];
		array[j] = array[l];
		array[l] = temp;
		//继续进行排序
		__quickSortBase(array,l,j-1);
		__quickSortBase(array,j+1,r);		
	}

20 generates a number of 0 to 66, were tested:

This version can be optimized:

① before each sorting, random element swap leftmost first array and the array bit, and then take the leftmost array element e do intermediary.

Role: to resolve when almost the whole orderly array sort will lead to inefficiencies.


	public static void __quickSortBase(int[] array,int l,int r){
		int temp;
		if(l>=r){
			return ;
		}
		//优化1:先随机取下标,然后与最左元素交换下
		int index = (int) (Math.random()*(r-l)+l);
		temp = array[l];
		array[l] = array[index];
		array[index] = temp;

		int e = array[l];
		int j = l;//保存<e部分尾部的下标
		for(int i=l+1;i<=r;i++){//将数组分为<e和>=e两部分
			if(array[i]<e){
				temp = array[j+1];
				array[j+1] = array[i];
				array[i] = temp;
				j++;
			}
		}
		//排序完成后,将array[j]与array[l]进行交换,此时l~j-1为<e部分,j+1~r为>=e部分
		temp = array[j];
		array[j] = array[l];
		array[l] = temp;
		//继续进行排序
		__quickSortBase(array,l,j-1);
		__quickSortBase(array,j+1,r);		
	}

② When a small number of elements to be sorted portion when optimized version of insertion sort, efficiency

	public static void __quickSortBase(int[] array,int l,int r){
		int temp;
//		if(l>=r){
//			return ;
//		}
		//优化2:使用优化版的插入排序改进效率
		if(r-l<=15){
			insertionSortBetter(array, l, r);
			return ;
		}
		
		//优化1:先随机取下标,然后与最左元素交换下
		int index = (int) (Math.random()*(r-l)+l);
		temp = array[l];
		array[l] = array[index];
		array[index] = temp;

		int e = array[l];
		int j = l;//保存<e部分尾部的下标
		for(int i=l+1;i<=r;i++){//将数组分为<e和>=e两部分
			if(array[i]<e){
				temp = array[j+1];
				array[j+1] = array[i];
				array[i] = temp;
				j++;
			}
		}
		//排序完成后,将array[j]与array[l]进行交换,此时l~j-1为<e部分,j+1~r为>=e部分
		temp = array[j];
		array[j] = array[l];
		array[l] = temp;
		//继续进行排序
		__quickSortBase(array,l,j-1);
		__quickSortBase(array,j+1,r);		
	}

Dual quick sort

Sort ideas: firstly passed the array to be sorted, using a variable array subscript l represents a starting point, using the variable array subscript r represents the end point, and then take the first left element of the array v do intermediary, declared initial value of the variable i l + 1 , declare the variable j initial value of r, if i <= r && array [i ] is smaller than v, i ++, until the array [i]> = v; if j> = l + 1 && array [j] is larger than v, j--, until array [j] <= v; exchange array [i] and array [j], to ensure subscript from l ~ array element i is less than equal to v, index from j ~ array elements r are greater than or equal v, then i ++, j--; cycle is completed, j is the position of the last element position in the array <= v, and which the array [l] exchange, and then continue to l ~ j-1 and j + 1 ~ r of two parts dual fast row.

Code:

//双路快排,解决大量重复值的数组排序
	public static void quickSort2(int[] array){
		_quickSort2(array,0,array.length-1);
	}
	
	
	public static void _quickSort2(int[] array,int l,int r){
		//数组数量小时,用优化版插入排序提高效率
		if(r-l<=15){
			insertionSortBetter(array, l, r);
			return ;
		}
		//优化:先随机取下标,然后与最左元素交换下
		int index = (int) (Math.random()*(r-l)+l);
		int temp = array[l];
		array[l] = array[index];
		array[index] = temp;
		
		int v = array[l];//最左侧元素做中介
		
		int i = l+1,j = r;
		while(true){
			while(i<=r&&array[i]<v){i++;}//如果array[i]小于v,i++;直到碰到不小于v的元素时停止
			while(j>=l+1&&array[j]>v){j--;}//如果array[j]大于v,j--;直到碰到不大于v的元素时停止
			if(i>j){break;}
			//交换array[i]和array[j],保证下标从l~i的元素值均小于等于v,下标从j~r的元素值均大于等于v
			temp = array[i];
			array[i] = array[j];
			array[j] = temp;
			i++;
			j--;
		}
		//循环结束后,j位于<=v的最后一个元素位置,交换array[j]和array[l];此时l~j均小于等于v,下标从j~r的元素值均大于等于v,array[j]==v
		temp = array[l];
		array[l] = array[j];
		array[j] = temp;
		
		_quickSort2(array,l,j-1);
		_quickSort2(array,j+1,r);
		
	}

Three-way quick sort

 
Sort ideas:
firstly passed the array to be sorted, using a variable array subscript l represents a starting point, using the variable array subscript r represents the end point, and then take the first left element of the array v do intermediary, declared initial value of the variable i l + 1 , declare variables L lt initial value, the initial value of variable declaration gt r + 1, divided into three parts first array, array [l + 1] ~ array [lt] section <v, array [gt] to array [ r] section> v, array [lt + 1 ] ~ array [i] portion == v; if i <entering the loop processing array gt. If the array [i] <v, which is the lt + 1 exchange, and lt ++, this time l + 1 ~ lt portions is less than v, lt through i a portion equal to V; if the array [i]> v, which is the gt-1 exchange, and gt--, gt ~ r at this time is greater than V portion; if the array [i] == v, i ++ can directly. When the loop terminates, lt is located in a last array <v part, which is interchangeable with array [L], this time portion array [l] ~ array [lt -1] is <v, array [lt] to array [gt-1] portion == v, array [gt] to array [r] section> v. Then proceeds to the three-way is greater than v and v is less than two-part quick drain.

Code:

	// 三路快排,将数组分为<v,==v,>v三部分处理
	public static void quickSort3(int[] array) {
		_quickSort3(array, 0, array.length - 1);
	}

	public static void _quickSort3(int[] array, int l, int r) {
		// 数组数量小时,用优化版插入排序提高效率
		if (r - l <= 15) {
			insertionSortBetter(array, l, r);
			return;
		}
		// 优化:先随机取下标,然后与最左元素交换下
		int index = (int) (Math.random() * (r - l) + l);
		int temp = array[l];
		array[l] = array[index];
		array[index] = temp;

		int v = array[l];// 最左侧元素做中介
		
		int i=l+1,lt=l,gt=r+1;//array[l+1...lt]<v,array[gt...r]>v,array[lt+1....i]==v
		
		while(i<gt){
			if(array[i]<v){//将其与lt+1交换,并且lt++,此时l+1~lt的部分小于v,lt到i的部分等于v
				temp = array[i];
				array[i] = array[lt+1];
				array[lt+1] = temp;
				lt++;
				i++;
			}
			else if(array[i]>v){//将其与gt-1交换,并且gt--,此时gt~r的部分大于v
				temp = array[i];
				array[i] = array[gt-1];
				array[gt-1] = temp;
				gt--;				
			}else{//直接i++
				i++;
			}
		}
		//循环结束后,lt位于小于v的部分的最后一个元素,将其与最左侧交换
		temp = array[l];
		array[l] = array[lt];
		array[lt] = temp;
		
		//继续对小于v和大于v的两部分进行三路快排
		_quickSort3(array, 0, lt-1);
		_quickSort3(array, gt, r);
		
	}

 

Guess you like

Origin blog.csdn.net/A1344714150/article/details/88789649