Quick sort of classic algorithm

Applicable scene:

The sub-problems are of the same nature as the original problem

Sub-problems are independent of each other (different from dynamic programming)

Classic case 1: Binary search

Basic idea: The premise is to give an ordered array, and then perform a binary search.

Classic case 2: Quick sort

Basic idea:

  1. Select a pivot element (the first element)
  2. Two pointers front/rear, pointing to the beginning and the end respectively
  3. Move rear to find the first occurrence of a value smaller than the reference element pivot
    Move front to find the first occurrence of a value greater than the reference element pivot
  4. Change the values ​​of the two elements and continue to move the pointer. The purpose is to make the left half of the last overlapping pointer smaller than the reference element pivot , and half of the pointer is larger than the reference element pivot
    until front==rear
  5. Swap the element where the current pointer is located with the pivot element, so that the left half is all smaller than the reference element pivot , and half is all greater than the reference element pivot
  6. At this time, according to the idea of ​​divide and conquer algorithm, the array is divided into two parts [2, 3, 1] and [6, 7, 5, 8], and then recursively sort again.

Code

/*
    快排: 找到index后,快排转化成了分治算法
    1. 先找到中间索引 index
    2. quickSort(Array, 0, index - 1);
    3. quickSort(Array, index + 1, end)
*/
#include <stdio.h>
#include <stdlib.h>

int arr[] = {4,7,6,5,3,2,8,1};

int GetIndex(int* arr, int low, int hight) {
    int pivot = low;
    int front = low;
    int rear = hight;
    int tmp=0;
    while (front != rear)
    {
        if(arr[rear] > arr[pivot] ) {
            rear--;
        }
        else {
            if(arr[front] < arr[pivot]) {
                front++;
            }
            else {
                tmp = arr[front];
                arr[front] = arr[rear];
                arr[rear] = tmp;
                rear--;
            }
        }   
    }
    
    tmp = arr[pivot];
    arr[pivot] = arr[front];
    arr[front] = tmp;
    return front;
}

void quickSort(int* arr, int low, int hight) {
    if(low> hight) {
        return;
    }
    int index = GetIndex(arr, low, hight);
    quickSort(arr, low, index - 1);
    quickSort(arr, index + 1, hight);
}

int main() {
    quickSort(arr, 0, sizeof(arr)/sizeof(arr[0]) -1);
    for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); ++i) {
        printf("%d\t",arr[i]);
    }
    printf("\n");
}

Easy to make mistakes

When moving the pointer, you need to move rear first, then front. Otherwise, some elements in the array will be in the wrong order.

As shown in the above figure, if you move the front first, then when the pivot value is exchanged at the end, 6 and 4 are exchanged, then the left half of the array value at this time is not all less than pivot 4, so you cannot move the front pointer first

Guess you like

Origin blog.csdn.net/weixin_44937328/article/details/115343012