W. :递归版插入排序

来源:互联网 发布:201淘宝开店成功经验 编辑:程序博客网 时间:2024/05/16 14:37

//author: W.
//递归版插入排序. 2.3-4 P22
//时间复杂度: O(n^2)
#include <stdio.h>

//这个查找并不是找到与key相等的位置,而是找到第一个大于key的位置
//二分查找的时间复杂度是O(lgn)
//利用循环不变式方式进行迭代方式的查找
int binary_search_index1(int a[], int begin, int end, int key)
{
    int mid;
    if(a[end] <= key)
    {
        return -1;
    }
    //循环不变式初始化:a[end] > key
    while(begin < end) //保持:a[end] > key 并且begin < end.这里当begin == end且a[end] > key时,此时的end即待插入位置
    {
        mid = (begin + end) / 2;
        if(a[mid] <= key)
        {
            begin = mid + 1;
        }
        else
        {
            end = mid;//这里a[mid]可以确定大于key,但a[mid-1]未必大于key.要注意保持循环不变式保持条件成立.
        }
    }//循环终止时,a[end]为第一个大于key的值.
    return end;
}

//利用递归方式的查找
int binary_search_index2(int a[], int begin, int end, int key)
{
    if(a[end] <= key) //其实这个相当于初始条件,第一次进入该函数时要确定a[end]是否大于key,以后每次递归时,要保证参数的a[end]>key,然后在begin == end时停止递归
    {
        return -1;
    }
    if(begin >= end) //这个才是递归操作的真正退出条件,即最小规模问题
    {
        return end;
    }
    int mid;
    mid = (begin + end) / 2;
    if(a[mid] <= key)
    {
        return binary_search_index2(a, mid+1, end, key);
    }
    else
    {
        return binary_search_index2(a, begin, mid, key);
    }
}

//但是插入操作需要移位操作,移位操作的时间复杂度是O(n)
//该函数的调用前提是a[0]~a[key_index-1]已排序,该函数利用二分查找的方式找到待查位置并执行插入元素的操作
void insertion(int a[], int key_index)
{
    if(key_index == 0) //只有一个元素时,已排序.
    {
        return;
    }
    int key = a[key_index];
    int search_index = binary_search_index1(a, 0, key_index - 1, key);
    //int search_index = binary_search_index2(a, 0, key_index - 1, key);
    //printf("search_index = %d/n",search_index);
    if(search_index < 0)
    {
        return; //已排序
    }
    int i;
    for(i = key_index; i >= search_index; --i)//移位
    {
        a[i] = a[i-1];
    }
    a[search_index] = key; //插入
}

//总的插入排序的时间复杂度还是O(n^2)
void insertion_recursive_sort(int a[], int length)
{
    if(length > 1)
    {
        insertion_recursive_sort(a, length -1);
        insertion(a, length -1);
    }
    //当length == 1时,已排序
}

void test_sort()
{
    int a[] = { 5, 2, 4, 6, 1, 3, 10, 6, 7, 9, 8, 123, 233, 3, 23, 33, 1134, 454353, 2, 0, 0, 0, 1};
    int i;
    for(i = 0; i < sizeof(a)/sizeof(int); ++i)
    {
        printf("%d ", a[i]);
    }
    printf("/n");

    insertion_recursive_sort(a, sizeof(a)/sizeof(int));
   
    for(i = 0; i < sizeof(a)/sizeof(int); ++i)
    {
        printf("%d ", a[i]);
    }
    printf("/n");
}

int main(int argc, char** argv)
{
    test_sort();
    return 0;
}
//输出:
//5 2 4 6 1 3 10 6 7 9 8 123 233 3 23 33 1134 454353 2 0 0 0 1
//0 0 0 1 1 2 2 3 3 4 5 6 6 7 8 9 10 23 33 123 233 1134 454353

原创粉丝点击