内部排序之插入排序(直接插入排序,二分插入排序,希尔插入排序)
2017-03-26 16:40
676 查看
目录
直接插入排序简介及其代码二分插入排序简介及其代码
希尔插入排序简介及其代码
插入排序总结
直接插入排序简介及其代码
简介:直接插入排序过程:
代码块:
#include<stdio.h> #include<stdlib.h> #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<stdio.h> #include<stdlib.h> #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,将所有的元素放到一个序列中为止。
希尔插入过程
代码块:
#include<stdio.h> #include<stdlib.h> #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会发生位置上的变化。
相关文章推荐
- 数据结构-排序算法之插入排序(直接插入,二分插入,希尔,表插入)
- 插入排序(直接插入排序和希尔(shell)排序
- 三种常用的插入排序算法--直接插入排序、二分插入排序、希尔排序
- 优化的直接插入排序(二分查找插入排序,希尔排序)
- 常见排序集合(冒泡排序,选择排序,直接插入排序,二分插入排序,快速排序,希尔排序,归并排序)
- 插入排序——直接插入排序、二分插入排序、希尔排序
- 直接插入排序、二分插入排序、希尔排序、冒泡排序与简单选择排序
- Python使用二分插入排序竟然比直接插入排序快99倍!
- 8.1 内部排序法---插入类排序(直接插入、折半、希尔)
- 内部插入排序---直接插入排序
- 数据结构图文解析之:直接插入排序及其优化(二分插入排序)解析及C++实现
- 排序算法之直接插入排序、二分插入排序和希尔排序
- Java使用二分插入排序竟然和直接插入排序速度相差不多
- C实现三种插入排序-简单插入排序、二分插入排序、希尔插入排序
- 内排序——插入排序—直接插入(稳定)—希尔(不稳定)
- Java选择排序、冒泡排序、直接插入排序与二分查找
- 插入排序(直接插入排序、希尔排序)
- C++数据结构 排序 二分 插入 冒泡 基数 归并 直选 快排 希尔 堆排序
- 排序一:插入排序(直接插入排序)