Data Structure Algorithm Learning Summary - MOOC (9) Quick Sort (from small to large)

Data Structure Algorithm Learning Summary - MOOC (9) Quick Sort (from small to large)

1. Review

The previous section is down to bottom-up merge sort

This section will talk about a high-performance sort, quicksort

2. Analysis

The idea of ​​quick sort is to first take the first element of the array, denoted it as v, and find a suitable position p, satisfying that the elements before the p position are all less than v, and the elements after p are greater than or equal to v, and then for less than v and Elements greater than or equal to v are then sorted recursively

For the array {4,5,1,3}, 4 is recorded as v, compare 5 and 4, 5 is larger than 4, and continue to the next element 1; 1 and 4 are compared and found that 1 is smaller than 4, then swap 5 and 1 position, now the array becomes {4,1,5,3}; compare 3 and 4, find that 3 is smaller than 4, swap the positions of 5 and 3, now the array becomes {4,1,3,5}, finally swap At the positions of 3 and 4, the array becomes {3,1,4,5}, the elements before 4 are less than 4, the elements after 4 are greater than or equal to 4, and then 3,1 can be sorted

3. Actual combat

QuickSort.h

#ifndef QUICKSORT_H_
#define QUICKSORT_H_
#include <iostream>
using namespace std;
/**
 * Partition operation on the [l...r] part
 * Return p such that arr[l...p-1]<arr[p],arr[p+1,r]>=arr[p]
 */
template<typename T>
int __partition(T arr[],int l,int r){
	T v = arr[l];

	//arr[l+1...j] < v ,arr[j+1...i] >= v
	int j = l;
	for(int i = l+1;i<=r;i++){
		if(arr[i] < v){
			swap(arr[j+1],arr[i]);
			j++;
		}
	}
	swap(arr[l],arr[j]);

	return j;
}

/**
 * Quick sort the arr[l...r] part
 */
template<typename T>
void __quickSort(T arr[],int l,int r){
	if(l >= r)
		return;

	int p = __partition(arr,l,r);
	__quickSort(arr,l,p-1);
	__quickSort(arr,p+1,r);
}

template<typename T>
void quickSort(T arr[],int n){
	__quickSort(arr,0,n-1);
}

#endif /* QUICKSORT_H_ */

4. Think

For an array that is nearly ordered or has many duplicate key values, such a quick sort is actually very inefficient. Although the theoretical time complexity is nlogn level, the time complexity at this time may degenerate to the worst n^ Level 2

5. Optimization

For nearly ordered arrays

#ifndef QUICKSORT_H_
#define QUICKSORT_H_

#include <iostream>
#include "InsertSort.h"
using namespace std;
/**
 * Partition operation on the [l...r] part
 * Return p such that arr[l...p-1]<arr[p],arr[p+1,r]>=arr[p]
 */
template<typename T>
int __partition(T arr[],int l,int r){
	swap(arr[l],arr[rand()%(r - l +1)+l]);
	T v = arr[l];

	//arr[l+1...j] < v ,arr[j+1...i] >= v
	int j = l;
	for(int i = l+1;i<=r;i++){
		if(arr[i] < v){
			swap(arr[j+1],arr[i]);
			j++;
		}
	}
	swap(arr[l],arr[j]);

	return j;
}

/**
 * Quick sort the arr[l...r] part
 */
template<typename T>
void __quickSort(T arr[],int l,int r){
//	if(l >= r)
//		return;
	if(r - l<= 15){
		insertSort(arr,l,r);
		return;
	}

	int p = __partition(arr,l,r);
	__quickSort(arr,l,p-1);
	__quickSort(arr,p+1,r);
}

template<typename T>
void quickSort(T arr[],int n){
	__quickSort(arr,0,n-1);
	srand(time(NULL));
}

#endif /* QUICKSORT_H_ */

For arrays with many duplicate key values

Others remain unchanged, modify the partition

/**
 * Optimized partition to avoid extreme imbalance due to many duplicate key values
 */
template<typename T>
int __partition2(T arr[],int l,int r){
	swap(arr[l],arr[rand()%(r - l +1)+l]);
	T v = arr[l];

	//arr[l+1...i)<=v,arr[j...r]>=v
	int i = l+1,j = r;
	while(true){
		while(i<=r && arr[i] < v) i++;
		while(j>=l+1 && arr[j] > v) j--;
		if(i > j) break;
		swap(arr[i],arr[j]);
		i++;
		j--;
	}
	swap(arr[l],arr[j]);
	return j;
}

6. Opinions and Suggestions

If you have any questions or suggestions, please leave a message to discuss


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325746379&siteId=291194637