zoukankan      html  css  js  c++  java
  • 【C++】排序算法小结

    1、计数排序

    如果给定上下界,并且区间不大的话,最适用。

    比如对于英文字母数组进行排序。

    时间复杂度O(n),空间复杂度O(n)

    void countSort(int A[], int n, int low, int high)
    {
        int size = high-low+1;
        vector<int> count(size, 0);    //count[i] represents low+i appears count[i] times in A
        for(int i = 0; i < n; i ++)
        {
            count[A[i]-low] ++;
        }
        int ind = 0;
        for(int i = 0; i < size; i ++)
        {
            while(count[i])
            {
                A[ind ++] = low+i;
                count[i] --;
            }
        }
    }

    2、冒泡排序(基础版)

    最基础的排序算法,相邻元素两两比较并交换。

    时间复杂度O(n2),空间复杂度O(1)。稳定排序。

    void bubbleSort(int A[], int n)
    {
        for(int i = 0; i < n; i ++)
        {
            for(int j = 0; j < n-i-1; j ++)
            {
                if(A[j] > A[j+1])
                    swap(A[j], A[j+1]);
            }
        }
    }

    3、冒泡排序(加速版)

    如果中间结果已经有序,即一次遍历过程中不存在需要交换的相邻元素,则结束返回。

    时间复杂度O(n2),空间复杂度O(1)。稳定排序。

    void bubbleSortAc(int A[], int n)
    {
        bool exchange;
        for(int i = 0; i < n; i ++)
        {
            exchange = false;
            for(int j = 0; j < n-i-1; j ++)
            {
                if(A[j] > A[j+1])
                {
                    exchange = true;
                    swap(A[j], A[j+1]);
                }
            }
            if(exchange == false)
                return;
        }
    }

    4、选择排序

    遍历过程中选择最大元素,与末尾元素交换。

    时间复杂度O(n2),空间复杂度O(1)。不稳定排序。

    void selectSort(int A[], int n)
    {
        for(int i = n-1; i >= 0; i --)
        {
            int max = A[0];
            int ind = 0;
            for(int j = 1; j <= i; j ++)
            {
                if(A[j] > max)
                {
                    max = A[j];
                    ind = j;
                }
            }
            if(ind != i)
                swap(A[ind], A[i]);
        }
    }

    5、插入排序

    将当前元素插入局部有序的数组中。

    时间复杂度O(n2),空间复杂度O(1)。稳定排序。

    void insertSort(int A[], int n)
    {
        for(int i = 1; i < n; i ++)
        {//insert A[i] into the right place
            int cur = i-1;
            int value = A[i];
            while(cur >= 0 && A[cur] > value)
            {
                A[cur+1] = A[cur];
                cur --;
            }
            A[cur+1] = value;
        }
    }

    6、快速排序

    最常用的排序,使用pivot将数组分成大小两段,递归完成排序。

    时间复杂度平均O(nlogn),最坏情况(已排序或逆序)O(n2),空间复杂度O(1)。不稳定排序。

    int partition(int A[], int low, int high)
    {
        int pivot = A[low];
        int vacant = low;
        while(low < high)
        {
            while(high > low && A[high] >= pivot)
                high --;
            //A[high] < pivot
            if(high > low)
            {
                A[vacant] = A[high];
                vacant = high;
            }
            else
                break;
    
            while(low < high && A[low] <= pivot)
                low ++;
            //A[low] > pivot
            if(low < high)
            {
                A[vacant] = A[low];
                vacant = low;
            }
            else
                break;
        }
        A[low] = pivot;
        return low;
    }
    void quickSort(int A[], int low, int high)
    {
        if(low < high)
        {
            int pos = partition(A, low, high);
            quickSort(A, low, pos-1);
            quickSort(A, pos+1, high);
        }
    }

    7、堆排序

    分为建堆与交换两个过程。

    通常用于数组中寻找最大/小的k个元素。

    时间复杂度O(nlogn),空间复杂度O(1)。不稳定排序。

    void siftDown(int A[], int start, int end)
    {
        int temp = A[start];
        int i = start;
        int j = 2*i + 1;    //left child
        while(j <= end)
        {
            if(j+1 <= end && A[j]<A[j+1])
                j = j+1;    //choose the bigger
            if(temp >= A[j])
                break;
            else
            {
                A[i] = A[j];
                i = j;
                j = 2*i + 1;
            }
        }
        A[i] = temp;
    }
    void heapSort(int A[], int n)
    {
        //build max heap
        for(int i = (n-2)/2; i >= 0; i --)
            siftDown(A, i, n-1);
    
        //sort
        for(int i = n-1; i >= 0; i --)
        {
            swap(A[0], A[i]);
            siftDown(A, 0, i-1);    //not include the i_th node
        }
    }

    8、归并排序

    分为局部排序与有序归并。

    通常用于内存不足,需要与硬盘交互的排序。

    时间复杂度O(nlogn),空间复杂度O(n)。稳定排序。

    void merge(int A[], int start, int mid, int end)
    {
        int size1 = mid-start+1;
        int* L = new int[size1];
        for(int i = 0; i < size1; i ++)
            L[i] = A[start+i];
        int size2 = end-mid;
        int* R = new int[size2];
        for(int i = 0; i < size2; i ++)
            R[i] = A[mid+1+i];
        
        int i = 0;
        int j = 0;
        int ind = start;
        while(i < size1 && j < size2)
        {
            if(L[i] <= R[j])
            {
                A[ind] = L[i];
                ind ++;
                i ++;
            }
            else
            {
                A[ind] = R[j];
                ind ++;
                j ++;
            }
        }
        while(i < size1)
        {
            A[ind] = L[i];
            ind ++;
            i ++;
        }
        while(j < size2)
        {
            A[ind] = R[j];
            ind ++;
            j ++;
        }
    }
    void mergeSort(int A[], int start, int end)
    {
        if(start < end)
        {
            int mid = (start+end)/2;
            mergeSort(A, start, mid);
            mergeSort(A, mid+1, end);
            merge(A, start, mid, end);
        }
    }
  • 相关阅读:
    iphone界面详解
    Spring jdbcTemplate.queryForInt(sql)的奇怪问题,呵呵
    BCP 高效批量导入
    eclipse中javascript显示为乱码的解决办法
    spring jdbcTemplate返回RS
    Spring IOC DI 形象理解
    MOSS 2007 文档库事件处理
    showModalDialog和showModelessDialog使用心得
    XMLHTTP.open权限不够的解决
    体现JAVA中的面向对象思想,接口(抽象类)的用处 :饲养员给动物喂食物
  • 原文地址:https://www.cnblogs.com/ganganloveu/p/4151767.html
Copyright © 2011-2022 走看看