zoukankan      html  css  js  c++  java
  • 排序算法(2)

    5.希尔排序(Shell)

    void shellsort1(int num[], const int len)
    {
        if (len <= 1) return;
    
        int i, j, k, dlen, temp;
    
        for (dlen = len / 2; dlen > 0; dlen /= 2) //确定步长
        {
            for (i = 0; i < dlen; i++)
            {
                for (j = i + dlen; j < len; j += dlen)
                {
                    temp = num[j];
                    k = j - dlen;
                    while (k >= 0 && num[k] > temp)
                    {
                        num[k + dlen] = num[k];
                        k -= dlen;
                    }
                    num[k + dlen] = temp;
                }
            }
        }
    }
    
    void shellsort2(int num[], const int len)
    {
        int i, j, dlen, temp;
    
        for (dlen = len / 2; dlen > 0; dlen /= 2)
        {
            for ( i = dlen; i < len; i++) //从第二序列开始,前面为有序区
            {
                if (num[i] < num[i - dlen])
                {
                    temp = num[i];
                    j = i - dlen;
                    while (j >= 0 && num[j] > temp)
                    {
                        num[j + dlen] = num[j];
                        j -= dlen;
                    }
                    num[j + dlen] = temp;
                }
            }
        }
    }

    一行两种写法都可以,但是后者比较便于理解和书写。

    希尔排序时间复杂度为O(nlogn),不过无需额外开辟空间,属于不稳定排序。

    希尔排序的时间性能优于直接插入排序,原因如下:

    (1)当文件初态基本有序时,直接插入排序所需的比较和移动次数较多;

    (2)当n值较小时,n和n^2的差别也较小,即直接插入排序的最好时间复杂度O(n)和最坏时间复杂度O(n^2)差别不大。

    基于以上两点,在希尔排序开始时增量较大,分组比较多,每组的记录数目较少,故各组内直接插入排序较快。后来增量逐渐缩小,分组数目逐渐较少,各组记录数目逐渐增多,但由于文件基本接近有序状态,所以新的排序过程较快。

    6.快速排序(QuickSort)

    //快速排序
    template<typename T>
    void SWAP(T& a, T&b)
    {
        T temp = a;
        a = b;
        b = temp;
    }
    
    int Partition(int data[], int left, int right)
    {
        if (data == NULL || left < 0 || (right - left) <= 0)
        {
            assert(false);
        }
    
        int pivot = data[left]; //轴心元素
        while (left < right)
        {
            //末尾元素大于轴心元素数值时,不作处理,尾指针往前递进
            while (left < right&&data[right] >= pivot)
                --right;
    
            //找到第一个不满足data[right]>pivot的元素,让其与data[left]交换
            SWAP(data[left], data[right]);
    
            //当前端的元素小于轴心元素时,不作处理,头指针往后递进
            while (left < right&&data[left] <= pivot)
                ++left;
    
            //找到第一个不满足data[left]<pivot的元素,让其与data[right]交换
            SWAP(data[left], data[right]);
        }
    
        /*由于前面
        while(start<end&&arry[end]>=pivot)和while(start<end&&arry[start]<=pivot)的限定,
        保证了最后不会出现low>high的情况,因此最后low=high,该位置就是轴心元素在数组中的置。
        */
        return left;
    }
    
    void Qsort(int data[], int left, int right)
    {
        if (left < right)
        {
            //此步保证data[pivot]大于左边的元素小于右边的元素,arry[pivot]被正确安排
            int pivot = Partition(data, left, right);
            Qsort(data, left, pivot - 1);
            Qsort(data, pivot + 1, right);
        }
    }
    
    void QuickSort(int data[], const int& length)
    {
        if (data == NULL || length <= 1)
            return;
    
        Qsort(data, 0, length - 1);
    }

    很好玩的算法,理解确实要花一点时间。

    具体原理解释可以参考:http://blog.csdn.net/morewindows/article/details/6684558,结合里面的图解,学习曲线一下就降下来了。

    7.二分查找(随机乱入)

    //二分查找
    int binary_search(int data[], const int length, const int target)
    {
        if (data == NULL || length <= 0)
            return -1;
    
        int left = 0, right = length - 1, mid = 0;
    
        while (left <= right)
        {
            mid = (left + right) >> 1;
            if (data[mid] == target)
            {
                return mid;
            }
            else if (data[mid] < target)
            {
                right = mid - 1;
            }
            else if (data[mid] > target)
            {
                left = mid + 1;
            }
        }
    
        return -1;
    }

    剑指offer中有一个寻找旋转数组中最小值,二分查找的变形,蛮不错的。

  • 相关阅读:
    判断浏览器的类别
    第2章计算机系统第五版Aimin.rar
    QQ软件已被破坏或部分文件丢失
    关于SqlServer服务无法启动的症状分析和解决方法
    T4模版生成SpringMVC构造REST代码:第三篇 用T4模版生成POCO类代码
    《深入理解计算机系统》笔记(四)虚拟存储器,malloc,垃圾回收【插图】
    Cocos2dx高级开发教程:制作自己的《捕鱼达人》
    算法设计与分析基础(第3版 影印版)
    MySQL数据库常用操作
    第一次面试
  • 原文地址:https://www.cnblogs.com/jason1990/p/4679370.html
Copyright © 2011-2022 走看看