内部排序之插入排序(直接插入排序,二分插入排序,希尔插入排序)

目录

  1. 直接插入排序简介及其代码
  2. 二分插入排序简介及其代码
  3. 希尔插入排序简介及其代码
  4. 插入排序总结

直接插入排序简介及其代码

简介:
内部排序之插入排序(直接插入排序,二分插入排序,希尔插入排序)_第1张图片
直接插入排序过程:
内部排序之插入排序(直接插入排序,二分插入排序,希尔插入排序)_第2张图片
代码块:

#include
#include
#define MAXSIZE 100
typedef int KeyType;
typedef struct
{
    KeyType key;
    int data;
}RecType;
void InsertSort(RecType R[], int n)
{
    int i, j;
    RecType tmp;
    for (i = 1; i < n; i++)
    {
        tmp = R[i];
        j = i - 1;
        while (j >= 0 && tmp.key < R[j].key)
        {
            R[j + 1] = R[j];
            j--;
        }
        R[j+1] = tmp;

    }
}

int main(void)
{
    int i,n = 10;
    RecType R[MAXSIZE];
    KeyType a[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
    for (i = 0; i < n; i++)
    {
        R[i].key = a[i];
    }
    printf("排序前");
    for (i = 0; i < n; i++)
    {
        printf("%d ", R[i].key);
    }
    printf("\n");
    InsertSort(R, n);
    printf("排序后");
    for (i = 0; i < n; i++)
    {
        printf("%d ", R[i].key);
    }
    printf("\n");
    system("pause");
    return 0;

}

二分插入排序简介及其代码

算法的基本过程:
折半插入排序只是在寻找数的过程中用折半查找法,再移动数据过程中依然用的是传统的插入方法
对于有序的数据序列,采用折半查找法去判断在何处插入i位置上的数据,就大大减少了需要比较的次数。

1)计算 0 ~ i-1 的中间点,用 i 索引处的元素与中间值进行比较,如果 i 索引处的元素大,说明要插入的这个元素应该在中间值和刚加入i索引之间,反之,就是在刚开始的位置 到中间值的位置,这样很简单的完成了折半;

2)在相应的半个范围里面找插入的位置时,不断的用(1)步骤缩小范围,不停的折半,范围依次缩小为 1/2 1/4 1/8 …….快速的确定出第 i 个元素要插在什么地方;

3)确定位置之后,将整个序列后移,并将元素插入到相应位置。

代码块:

#include
#include
#define MAXSIZE 100
typedef int KeyType;
typedef struct
{
    KeyType key;
    int data;
}RecType;
void InsertSort(RecType R[], int n)
{
    int i, j, low, high, mid;
    RecType tmp;
    for (i = 1; i < n; i++)
    {
        tmp = R[i];
        low = 0;
        high = i- 1;
        while (low <= high)//只有low>high时才会跳出while循环
        {
            mid = (high + low) / 2;
            if (tmp.key < R[mid].key) //要插入的数比R[mid]小,HIGH-1
            {
                high = mid - 1;
            }
            else//要插入的数比R[mid]大,LOW+1;
            {
                low = mid + 1;
            }
        }
        for (j = i - 1; j >= high+1; j--)
        {
            R[j + 1] = R[j];
        }
        R[high + 1] = tmp;
    }

}
int main(void)
{
    int i, n = 10;
    RecType R[MAXSIZE];
    KeyType a[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
    for (i = 0; i < n; i++)
    {
        R[i].key = a[i];
    }
    printf("排序前");
    for (i = 0; i < n; i++)
    {
        printf("%d ", R[i].key);
    }
    printf("\n");
    InsertSort(R, n);
    printf("排序后");
    for (i = 0; i < n; i++)
    {
        printf("%d ", R[i].key);
    }
    printf("\n");
    system("pause");
    return 0;

}

希尔插入排序及其代码

基本思想
设初始序列有n个元素,选定一个小于n大于或等于1的整数gap作为间隔,将全部元素分成gap个子序列,所有距离为gap的元素放在同一个子序列中,在每个子序列中分别采用直接插入算法进行排序;然后缩小间隔gap,如令gap=gap/2,重复上面的子序列划分和子序列排序动作;直到最后去gap=1,将所有的元素放到一个序列中为止。
内部排序之插入排序(直接插入排序,二分插入排序,希尔插入排序)_第3张图片

希尔插入过程
内部排序之插入排序(直接插入排序,二分插入排序,希尔插入排序)_第4张图片

代码块:

#include
#include
#define MAXSIZE 100
typedef int KeyType;
typedef struct
{
    KeyType key;
    int data;
}RecType;
void ShellSort(RecType R[],int n)
{
    int i, j, gap, k;
    RecType tmp;
    gap = n / 2;
    while (gap > 0)
    {
        for (i = gap; i < n; i++)
        {
            tmp = R[i];
            j = i - gap;
            while (j >= 0 && tmp.key < R[j].key)
            {
                R[j + gap] = R[j];
                j = j - gap;
            }
            R[j + gap] = tmp;
            j = j - gap;
        }
        gap = gap / 2;
    }
}
int main(void)
{
    int i, n = 11;
    RecType R[MAXSIZE];
    KeyType a[] = { 10,9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
    for (i = 0; i < n; i++)
    {
        R[i].key = a[i];
    }
    printf("排序前");
    for (i = 0; i < n; i++)
    {
        printf("%d ", R[i].key);
    }
    printf("\n");
    ShellSort(R, n);
    printf("排序后");
    for (i = 0; i < n; i++)
    {
        printf("%d ", R[i].key);
    }
    printf("\n");
    system("pause");
    return 0;
}

插入排序总结

1、 直接插入排序:

① 思想:最基本的插入排序,将第i个插入到前i-1个中的适当位置。

② 时间复杂度:T(n) = O(n²)。

③ 空间复杂度:S(n) = O(1)。

④ 稳定性:稳定排序。循环条件while(r[0].key < r[j].key)保证的。

2、 折半插入排序:

① 思想:因为是已经确定了前部分是有序序列,所以在查找插入位置的时候可以用折半查找的方法进行查找,提高效率。

② 时间复杂度:比较时的时间减为O(n㏒n),但是移动元素的时间耗费未变,所以总是得时间复杂度还是O(n²)。

③ 空间复杂度:S(n) = O(1)。

④ 稳定性:稳定排序。

3、 希尔排序:

① 思想:又称缩小增量排序法。把待排序序列分成若干较小的子序列,然后逐个使用直接插入排序法排序,最后再对一个较为有序的序列进行一次排序,主要是为了减少移动的次数,提高效率。原理应该就是从无序到渐渐有序,要比直接从无序到有序移动的次数会少一些。

② 时间复杂度:O(n的1.5次方)

③ 空间复杂度:O(1)

④ 稳定性:不稳定排序。{2,4,1,2},2和1一组4和2一组,进行希尔排序,第一个2和最后一个2会发生位置上的变化。

你可能感兴趣的:(数据结构)