8-直接插入排序&希尔排序

直接插入排序

时间复杂度:无序O(n^2) 有序O(n)
空间复杂度:O(1)
算法稳定性:稳定
原理:
把一个元素按升序或(降序)插入已经有序的一个序列里面,插入后保持序列的有序。
假设有序列arr[1…n],则将arr[2]插入arr[1…1]中,将arr[3]插入arr[1…2]中,
将arr[4]插入arr[1…3]中。如此经过n-1次的插入,便可以使arr[1…n]有序。
把待插入数与已有序的数列依次比较,找到合适位置,进行数据挪动,插入到合适位置。
(一直分为排序好的和无序的两个部分,从待排序的数值里找一个插入到排序好的数值里)
例:4 1 5 12 0
第一趟:tmp=1 1<4 1 4
第二趟:tmp=5 1 4 5
第三趟:tmp=12 1 4 5 12
第四趟:tmp=0 0<12,0<5,0<4,0<1 0 1 4 5 12
在这里插入图片描述

void Insert_Sort(int *arr, int len)
{
    int i,j;
    int tmp=0;
    for (i = 1; i < len; i++)
    {
        tmp = arr[i];//把将要比较的值放入tmp里
        for (j = i - 1; j >= 0; j--)//j在i的前一位
        {
            if (tmp < arr[j])//如果tmp里的值比j的值小就互换tmp和j的值
            {
                arr[j + 1] = arr[j];//即把j里的值放在下一位,把tmp的值放在原来j的位置
            }
            else
            {
                break;
            }
        }
        arr[j + 1] = tmp;//不是则就放在它原来的位置,包扩j减到-1位置 j+1位0号位置
    }
}

希尔(shell)排序 :直接插入的优化

分组的直接插入排序—》先对数据进行分组,使用直接插入算法使得组内有序再分组,在直接插入使组内有序,直到分组只有一个
时间复杂度:O(n1.3)——O(n1.5)
空间复杂度:O(1)
算法稳定性:不稳定
原理:设定一个增量gap,每次插入排序使相距为d的元素排成一个有序列,
然后缩小增量,继续插入排序,最后一次gap=1,排序完成 。
在进行大量数据排序上,效率较高,因为相比于冒泡,选择排序,
其每次操作省略了三步赋值的开销,只有一步。
在这里插入图片描述
版本1

void Shell(int *arr, int len,int gap)
{   
    int i, j;
    int tmp = 0;
    for (i = gap; i < len; i++)
    {
        tmp = arr[i];
        for (j = i - gap; j >= 0; j-=gap)
        {
            if (tmp < arr[j])
            {
                arr[j + gap] = arr[j];
            }
            else
            {
                break;
            }
        }
        arr[j + gap] = tmp;
    }
}
void Shell_Sort(int *arr, int len)
{
    int drr[] = { 5,3,1 };//素数数组
    int lend = sizeof(drr) / sizeof(drr[0]);
    for (int i = 0; i < lend; i++)
    {
        Shell(arr, len, drr[i]);
    }
}

主函数及测试:

void Show(int *arr,int len)
{
    for (int i = 0; i < len; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
}


int main()
{
    int arr[] = {12,45,68,76,24,5};
    int len = sizeof(arr) / sizeof(arr[0]);
    //Select_Sort(arr, len);
    //Bubble_Sort(arr, len);
    Bubble_Sort2(arr,len);
    //Insert_Sort(arr,len);
    Show(arr, len);
    /*int arr[] = { 12,45,68,76,24,5,85,65,2,4,78,95 };
    int len = sizeof(arr) / sizeof(arr[0]);
    Shell_Sort(arr, len);
    Show(arr, len);*/
}

版本2

void Shell(int *arr, int len, int t)
{
    int i = t;
    int j = 0;
    int tmp = 0;
    while (i < len)
    {
        tmp = arr[i];
        j = i - t;
        while (j >= 0 && arr[j] > tmp)
        {
            arr[j + t] = arr[j];
            j -= t;
        }


        arr[j + t] = tmp;
        i++;
    }
}


//  O(n^1.3--1.5)    O(1)   不稳定
void ShellSort(int *arr, int len)
{
    int d[] = { 7, 5, 3, 1 };
    for (int i = 0; i < sizeof(d) / sizeof(d[0]); ++i)
    {
        Shell(arr, len, d[i]);
    }
}
发布了82 篇原创文章 · 获赞 7 · 访问量 4195

猜你喜欢

转载自blog.csdn.net/sunshine612/article/details/104701534