zoukankan      html  css  js  c++  java
  • 插入排序

    直接插入排序

    将待排序列分为已排序序列和未排序序列,不断取出未排序序列中的元素放入已排序序列中合适的位置(指放之后已排序序列仍然有序)。下面的例子中,是一个待排的数组arr,先将0位置的元素认为是一个有序序列,1~len(arr)-1为无序,慢慢从1开始取元素加入有序部分,直到所有数组元素有序。

    #include <iostream>
    
    using namespace std;
    
    void insert_sort(int arr[], int len)
    {
        int temp, i, j;
        for(i = 1; i < len ; i++)        //0位置单个元素默认有序,从1开始
        {
            temp = arr[i];               //temp保存每一轮想要排序的元素
            j = i - 1;                   //j为已排序序列的末尾元素的位置
            while(j>=0 && arr[j]>k)       //在已排序序列内,查找k的大小位置
            {
                arr[j+1] = arr[j];       //将元素后移,为k腾出空位
                j--;                     //在已排序序列内,由后向前循环
            }
            arr[j+1] = temp;                //将需要排序的元素放到腾出的空位上
        }
    }
    
    int main()
    {
        int arr[] = {7, 1, 4, 8, 3, 2};
        int len = sizeof(arr)/sizeof(int);
        for(int i = 0; i < len; i++)
        {
            cout << arr[i] << endl;
        }
    
        cout << "-------" << endl;
    
        insert_sort(arr, len);
        for(int i = 0; i < len; i++)
        {
            cout << arr[i] << endl;
        }
        return 0;
    }
    

    折半插入排序

    在将一个新元素插入已排好序的数组的过程中,寻找插入点时,待插序列的首元素为arr[low],末元素为arr[high],比较时将待插入元素与arr[mid](mid=(low+high)/2)相比较,如果比参考元素大,则选择arr[low]到arr[m-1]为新的插入区域(即high=mid-1),否则选择arr[mid+1]到arr[high]为新的插入区域(即low=mid+1),如此直至low<=high不成立,即将此位置之后所有元素后移一位,并将新元素插入arr[high+1]。

    #include <iostream>
    
    using namespace std;
    
    void binary_insert_sort(int arr[], int len)
    {
        int k, i, j;
        int low, high, mid;
        for(i = 1; i < len; i++)
        {
            low = 0;
            high = i - 1;
            k = arr[i];                             //k用来保存待排序元素
            while(low <= high)                      //利用折半查找,确定待排序元素在已排序序列中的位置
            {
                mid = (low + high) / 2;
                if(arr[mid] < arr[i])
                {
                    low = mid + 1;
                }
                else{
                    high = mid - 1;
                }
            }
            for(j = i-1 ; j >= high+1 ; j--)       //元素会插在arr[high+1]这个位置,而从high到i-1的元素会后移
            {
                arr[j+1] = arr[j];
            }
            arr[j+1] = k;
        }
    
    }
    
    int main()
    {
        int arr[] = {7, 1, 4, 8, 3, 2};
        int len = sizeof(arr)/sizeof(int);
        for(int i = 0; i < len; i++)
        {
            cout << arr[i] << endl;
        }
    
        cout << "-------" << endl;
    
        binary_insert_sort(arr, len);
        for(int i = 0; i < len; i++)
        {
            cout << arr[i] << endl;
        }
        return 0;
    }
    

    希尔排序

    又称为缩小增量排序。基本思路是将待排序列分割成若干个子序列,对每个子序列进行排序,然后缩小分割量(比如原本每隔4个元素为一组,现在变为2个),继续对缩小后的子序列排序,直到最后分割量为1。

    #include <iostream>
    
    using namespace std;
    
    void shell_sort(int arr[], int len)
    {
        int gap;          //步长
        int i, j;
        for(gap = len / 2; gap > 0; gap = gap / 2)        //先取数组arr长度的一半,然后每次变为上次的1/2。
        {
            for(i = gap; i < len; i++)                    //这里需要注意
            {
                if( arr[i] < arr[i-gap])                  //下面的内容基本与直接插入排序差不多,只是变成了间隔gap的元素排序。
                {
                    int temp = arr[i];
                    j = i - gap;
                    while(j >= 0 && arr[j] > temp)
                    {
                        arr[j+gap] = arr[j];
                        j = j - gap;
                    }
                    arr[j+gap] = temp;
                }
            }
        }
    }
    
    int main()
    {
        int arr[] = {7, 1, 4, 8, 3, 2};
        int len = sizeof(arr)/sizeof(int);
        for(int i = 0; i < len; i++)
        {
            cout << arr[i] << endl;
        }
    
        cout << "-------" << endl;
    
        shell_sort(arr, len);
        for(int i = 0; i < len; i++)
        {
            cout << arr[i] << endl;
        }
        return 0;
    }
    

    注意点:从上面shell_insert()函数中截取一段(也是注释里需要注意那块),如下。

    for(i = gap; i < len; i++)
    {
        ...
    }
    

    排序并不是将某个子序列完全排完,再下一个子序列。而是所有子序列轮着来orz

  • 相关阅读:
    oracle数据库同步
    软件设计过程中常用的几种图(一)
    面向对象建模为基础的开发模式
    常用正则表达式
    js 创建一个浮动div
    DATALIST 绑定数据分页
    ASP.NET 3.5 Extensions CTP Preview Released
    重构是一种意识流
    重构随笔: 封装集合(Encapsulate Collection)
    乱笔.................table控件,带一列合并
  • 原文地址:https://www.cnblogs.com/echobiscuit/p/12968900.html
Copyright © 2011-2022 走看看