zoukankan      html  css  js  c++  java
  • 几种简单排序算法

    最简单的排序算法——冒泡排序:

     1 void bubble_sort(int *arr, int len)
     2 {
     3    int up, down;
     4    for(up = 0; up != len; ++ up)
     5    {
     6        for(down = 0; down != len - up - 1; ++ down)
     7        {
     8            if(arr[down] > arr[down + 1])
     9                swap(arr[down], arr[down + 1]);
    10        }
    11    }
    12 }
    View Code

    还有一种思路,就是从头排到尾,再从尾排到前,这样的做法与上面的做法时间复杂度是一样的,在这里就不予以实现了。

    当数组元素不多时,较快捷的排序算法就是——插入排序,实现代码如下:

    void insert_sort(int *arr, int len)
    {
        int pos, index, key;
        for(pos = 1; pos != len; ++ pos)
        {
            key = arr[pos];
            for(index = pos - 1; index >= 0; -- index)
            {
                if(arr[index] > key)
                    arr[index + 1] = arr[index];
                else
                    break;
            }
            arr[index + 1] = key;
        }
    }
    View Code

    插入排序是将数组从开头开始变成一小段有序序列,再将下一个元素插入适当的位置,使数组变为一个长度加1的有序序列,这样做便无需每次都遍历一边整个数组了。

    同样的情况下,另一种较快捷的排序算法是——选择排序,实现代码如下:

    void select_sort(int *arr, int len)
    {
        int index, pos, min;
        for(pos = 0; pos != len; ++ pos)
        {
            min = pos;
            for(index = pos + 1; index != len; ++ index)
            {
                if(arr[min] > arr[index])
                    min = index;
            }
            if(min != pos)
                swap(arr[min], arr[pos]);
        }
    }
    View Code

    选择排序较快捷的地方是:无需每次都交换元素,这样为系统节省了一部分交换元素的步骤。

    在数组元素较多时,快速排序就是一种不错的选择。

    第一种实现代码如下:

    static int func1(int *arr, int low, int high)       //普通方法
    {
        int key = arr[low];
        while(low < high)
        {
            while(low < high && arr[high] >= key)
                -- high;
            if(low >= high)
                break;
            else
                swap(arr[high], arr[low]);
    
            while(low < high && arr[low] <= key)
                ++ low;
            if(low < high)
                swap(arr[high], arr[low]);
        }
    
        return low;
    }
    
    void quick_sort(int *arr, int len)
    {
        if(len <= 10)
            insert_sort(arr, len);
        else
        {
            int index = func1(arr, 0, len - 1);
            quick_sort(arr, index + 1);
            quick_sort(arr + index + 1, len - index - 2);
        }
    }
    View Code

    该种实现,主要是依靠递归方法,每次将数组分成两部分,前面的部分都比中间元素小,后面的部分都比中间元素大,这样,递归到最后,这个数组便成为一个有序序列。

    第二种实现代码如下:

    static int func2(int *arr, int low, int high)       //快慢指针
    {
        int fast = low + 1, last = low;
        int key = arr[low];
        for(; fast <= high; ++ fast)
        {
            if(arr[fast] < key)
            {
                swap(arr[last + 1], arr[fast]);
                ++ last;
            }
        }
        swap(arr[low], arr[last]);
        return last;
    }
    
    void quick_sort(int *arr, int len)
    {
        if(len <= 10)
            insert_sort(arr, len);
        else
        {
            int index = func2(arr, 0, len - 1);
            quick_sort(arr, index + 1);
            quick_sort(arr + index + 1, len - index - 2);
        }
    }
    View Code

    该种是先,主要是依靠快慢指针的方法,每次快指针的元素比key小时,将快指针与慢指针的下一个元素交换,这样,快指针指向的元素始终都比key大,慢指针指向的元素,始终都比key小,最后再将arr[low]与慢指针交换,这样,key又一次变成了中间值,思路与普通方法一样,实现方法有一些改进。

    堆排序,就是每一次将数组建立成堆,这样最大的元素始终在最前面,然后我们将该元素与相应的后面元素交换,即可得到有序序列。

    堆排序实现代码如下:

    static void func(int *arr, int low, int high)
    {
        int index;
        int key = arr[low];
        for(index = 2 * low + 1; index <= high; index = 2 * index + 1)
        {
            if(index < high && arr[index] < arr[index + 1])
                ++ index;
            if(key > arr[index])
                break;
            arr[low] = arr[index];
            low = index;
        }
        arr[low] = key;
    }
    
    
    void heap_sort(int *arr, int len)
    {
        if(len <= 10)
            insert_sort(arr, len);
        else
        {
            int index;
            for(index = (len - 2) / 2; index >= 0; -- index)
                func(arr, index, len - 1);
            for(index = len - 1; index > 0; -- index)
            {
                swap(arr[0], arr[index]);
    
                func(arr, 0, index - 1);
            }
        }
    }
    View Code

    建立成堆的方法,就是将元素下标每次乘2,得到最低层的值,将低层中较大的值与父值比较,若比父值大,则将该值赋给父值,否则退出,将key保存的父值赋到当前下标的元素。

    由于算法部分有些地方比较难以理解,所以目前只能简单写出这几种算法,当然也可能有不完善的地方,以后会慢慢改进。

  • 相关阅读:
    Codeforces Round #348 (VK Cup 2016 Round 2, Div. 2 Edition) D. Little Artem and Dance
    HDU 5521 Meeting 最短路
    BZOJ 1051: [HAOI2006]受欢迎的牛 强连通缩点
    P2661 信息传递 强连通分量
    Codeforces Round #343 (Div. 2) C. Famil Door and Brackets
    HDU 4859 海岸线 最小割
    HDU 4162 Shape Number
    Codeforces Round #355 (Div. 2) D. Vanya and Treasure dp+分块
    bzoj 1295: [SCOI2009]最长距离 暴力+bfs最短路
    Codeforces Round #222 (Div. 1) C. Captains Mode 对弈+dp
  • 原文地址:https://www.cnblogs.com/gjn135120/p/4009814.html
Copyright © 2011-2022 走看看