Quick sort of eight sorts of data structure

quick sort

Quick sort, to put it bluntly, is the process of finding the correct index position for the benchmark data

1.1 Introduction of quick sort

Hill sorting is equivalent to the upgrade of direct insertion sorting, they belong to the insertion sorting class; heap sorting is equivalent to the upgrading of simple selection sorting, they also belong to the selection sorting class; and for the exchange sorting classThe upgraded version of bubble sort is quick sort

1.2 Basic idea of ​​quick sort

The record to be sorted is divided into two independent parts by one pass, and the key of one part of the record is smaller than that of the other part of the record , and the two parts of the record can be sorted separately to achieve the purpose of the entire sort.

1.3 Sorting process of quick sort

  1. First, set a cutoff value, and divide the array into left and right parts through the cutoff value.
  2. Collect the data greater than or equal to the cutoff value to the right of the array, and collect the data smaller than the cutoff value to the left of the array. At this time, each element in the left part is less than or equal to the cutoff value, and each element in the right part is greater than or equal to the cutoff value.
  3. Then, the left and right data can be sorted independently. For the array data on the left side, a boundary value can be taken to divide this part of the data into left and right parts, and the smaller value is placed on the left side, and the larger value is placed on the right side. The array data on the right can also be processed similarly.
  4. Repeating the above process, we can see that this is a recursive definition. After sorting the left part by recursion, recursively sort the order of the right part. When the sorting of the data in the left and right parts is completed, the sorting of the entire array is also completed.

In summary: divide and conquer + fill in numbers

1.4 Example description

With 12, 10, 8, 22, 5, 13, 28, 21, 11 we want to sort it from small to large Sorting process:
insert image description here
Detailed process:

  1. Set two pointers left and right, which initially point to the left end and right end of the sequence to be sorted respectively; in addition, a reference element tmp is also attached (the first one is generally selected, and the value of the reference tmp in this example is 20).
    insert image description here

  2. First search from right to left from the position indicated by right to find the first element smaller than tmp, and then record it at the position of the reference element.
    insert image description here

  3. Then search from left to right from the position pointed by left to find the first element greater than tmp, and then record it in the position pointed to by right.
    insert image description here

  4. Then continue to search from right to left from the position pointed by right to find the first element smaller than tmp, and then record it in the position pointed to by left.
    insert image description here

  5. Then, left continues to search from left to right for the first element greater than tmp. If left == right appears during the search, it means that the quick sort is over. At this point, record tmp at the position where left and right both point to.
    insert image description here
    The above is the detailed process of a round of quick sorting

Notice:

  • Downward division requires at least two data in this group before it is necessary to divide, 0 or 1 is not necessary
  • When dividing: find from right to left smaller than the benchmark (equal)
  • From left to right, find the one that is larger than the base value

1.5 code implementation

//一次划分函数  核心函数  //返回基准值最终所在下标
int Partition(int *arr, int left, int right)
{
    
    
	//先讲arr数组里的[left, right]的第一个值 作为基准值
	int tmp = arr[left];

	while(left < right)
	{
    
    
		while(left<right && arr[right] > tmp)//左右边界没有相遇且当前右边的值大于基准值tmp
		right--;

		if(left < right)//如果此时,左右边界没有相遇,那就只能证明右边right找到了一个小于等于基准值tmp的值
		{
    
    
			arr[left] = arr[right];
		}
		else
		{
    
    
			break;
		}
		

		while(left<right && arr[left] <= tmp)//左右边界没有相遇且当前左边的值小于等于基准值tmp
		left++;

		if(left < right)//如果此时,左右边界没有相遇,那就只能证明左边left找到了一个大于基准值tmp的值
		{
    
    
			arr[right] = arr[left];
		}
		else
		{
    
    
			break;
		}
		
	}

	arr[left] = tmp;//此时 因为 left == right
	return left;//return right ok
}

void Quick(int *arr, int left, int right)
{
    
    
	if(left < right)//通过left <right  保证[left, right]这个范围内至少两个数据
	{
    
    
		int par = Partition(arr, left, right);

		if(left < par-1)//基准值左半部分  至少有两个值才有必要去递归
		{
    
    
			Quick(arr, left, par-1);
		}
		if(par+1 < right)//基准值右半部分  至少有两个值才有必要去递归
		{
    
    
			Quick(arr, par+1, right);
		}
	}

}
void QuickSort(int *arr, int len)
{
    
    
	Quick(arr, 0, len-1);
}

1.6 Performance Analysis

The more chaotic, the faster, the more orderly, the slower

  1. time complexity:
    best case: O(nlogn) Each data element can be equally divided into two parts. get a complete binary tree;
    worst case: O(n^2) this number has only right subtree or left subtree, the number of comparisons is (n-1)+(n-2) + (n-3) + ... +1=n*(n-1 )/2 ;
    average case:O(nlogn)。
  2. Space complexity: O(1).
  3. Stability: Because the comparison and exchange of keywords is performed by jumping, the relative position of data elements will be changed; therefore, quick sort is an unstable sorting method, but it is also the sorting algorithm with the highest average efficiency in inner sorting.

(A Xiaobai, please correct me if I am wrong)

Guess you like

Origin blog.csdn.net/weixin_56935264/article/details/124504534