• 快速排序(Quick Sort)


    快速排序是初学者比较难理解的几个算法之一,这里尽可简单化地讲解,希望能帮到大家。

    快速排序基本步骤:

    1. 从数列中挑出一个元素,称为"基准"(pivot)。
    2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
    3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

    下面这幅图会帮助你理解。选中的pivot用蓝色表示:

    quick_sort

    原则上可以选择任何元素作为基准。

    # choose pivot
    swap a[1,rand(1,n)]

    # 2-way partition
    k = 1
    for i = 2:n, if a[i] < a[1], swap a[++k,i]
    swap a[1,k]
    → invariant: a[1..k-1] < a[k] <= a[k+1..n]

    # recursive sorts
    sort a[1..k-1]
    sort a[k+1,n]

    我们以数组arr[] = {2, 6, 4, 10, 8, 1, 9, 5, 11, 7}举个例子。

    选最后一个元素作为pivot。

    • PIVOT = 7 or arr[10]
    • 对区域0-9的数据迭代处理,把pivot放在一边
    • 从左边开始,i为索引(数组下标)
      • if(2 < pivot)  => move ahead
      • if(6 < pivot)  => move ahead
      • if(4 < pivot)  => move ahead
      • if(10 < pivot) => NO, STOP (i points to 10 and i = 3)
    • 换个方向,右边开始,j为索引(数组下标)
      • if(11 > pivot)  => move towards left
      • if(5 > pivot) => NO, STOP. (j points to 5 and j = 7)
    • If (i<j) , 交换arr[i]和arr[j]
      数组现在变成 {2, 6, 4, 5, 8, 1, 9, 10, 11, 7}
    • Increment i and decrease j.
    • Again we start i from 8 and j from 9.
    • We will get the array as:- {2, 6, 4, 5, 1, 8, 9, 10 ,11, 7} where (i = 5 and j = 4)
    • Swap the pivot element with arr[i].
    • Thus we have {2, 6, 4, 5, 1, 7, 9, 10, 11, 8}

    当PIVOT = 7的情况,所有比7小的数在7的左边,比7大的数在7右边,对左边部分和右边部分的数据在进行相同的排序,直到整个数组排完序。

    下面是算法实现:

    #include<stdio.h>
     
    //a simple function to swap two numbers
    void swap(int *i, int *j)
    {
        int temp = *i;
        *i = *j;
        *j = temp;
    }
     
    // a function to partition the array arr
    // having starting index as - start
    // and ending index as - end
    int partition(int arr[], int start, int end)
    {
        // we take the pivot to be the last element
        // that means all elements smaller
        // to it will be on left and larger on right
        int pivot = arr[end];
     
        // taking i and j to define the range, we leave the pivot
        int i = start;
        int j = end-1;
     
        // loop till in range
        while(i<=j)
        {
            // keep moving till the left element is smaller than pivot
            while(arr[i]<pivot)
                i++;
     
            // keep moving left till right element is larger
            while(arr[j]>pivot)
                j--;
     
            // we need to swap the left and right
            if(i<=j)
            {
                swap(&arr[i],&arr[j]);
                i++;
                j--;
            }
        }
     
        // once partitioned, we need to put the pivot at correct place
        swap(&arr[i],&arr[end]);
     
        // return the position of pivot
        return i;
    }
     
    void performQuickSort(int arr[], int start, int end)
    {
        //the terminating condition for recursion
        if(start<end)
        {
            // get the partition index
            int p = partition(arr, start, end);
     
            // perform quick sort on left sub part
            performQuickSort(arr, start, p-1);
     
            // perform quick sort on right sub part
            performQuickSort(arr, p+1, end);
        }
    }
     
    //defining a function to perform merge sort on array arr[] of given size
    void quickSort(int arr[], int size)
    {
        performQuickSort(arr, 0, size-1);
    }
     
    // driver program to test the above function
    int main(void)
    {
        int i;
        int arr[10] = {2, 6, 4, 10, 8, 1, 9, 5, 3, 7};
     
        quickSort(arr,10);
     
        printf("SORTED array:- ");
        for(i=0;i<10;i++)
            printf("%d ",arr[i]);
     
        return 0;
    }
  • 相关阅读:
    erlang使用gen_server实现质数服务器(手打代码,还debug了几个错误)
    Java
    某个数组,通过交换使所有奇数都在前半所有偶数都在后半,复杂度O(N)。
    Mybatis映射文件完整模板参照
    Spring集成MyBatis
    jdbc hibernate myBatis比较
    MySQL的简单使用-(一)
    jQuery框架Ajax常用选项
    POI操作Excel的API注意点总结
    Java反射机制练习
  • 原文地址:https://www.cnblogs.com/programnote/p/4724417.html
Copyright © 2020-2023  润新知