排序耗时的操作主要分为两种:查找比较、记录移位。

1.表插入排序

在查找比较基础上,尽量减少记录移位步数,可以令排序操作耗时降低,表插入排序正是为减少移位次数而出现的。

在数据结构上,数据是存储在静态数组(表)中,而每个数组除了数据关键字外还记录了表中下一个记录,按记录遍历的关键字则是排序的结果。

如:有如下需要排序的数据:

关键字 5 1 3 2 4
下一个记录的表中位置 - - - - -

排序后得到的表为

关键字 5 1 3 2 4
下一个记录的表中位置 -1 3 4 2 0

这里还需要提到重排记录的方法:

由于重排过程中,需要移动记录的位置,所以"下一个记录的表中位置"则会产生变化,而又因为重排过程中表中不同数据只会被访问一次,所以可以利用失效的"下一个记录的表中位置"记录未被访问的数据且因重排被移位的新位置。

重排时,以i记录已经排好的记录数量,p记录要重拍的关键字,如果p<i,表示要重拍的关键字被移位了,所以再获取表中的"下一个记录的表中位置"即可。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. typedef struct{
  5. int data;
  6. int next;
  7. }node;
  8. typedef struct{
  9. node *list;
  10. int head;
  11. }table;
  12.  
  13. int main(void){
  14. node *s;
  15. int cnt=0, k, cntmax=10, nexttemp, datatemp, kk;
  16. int head, preindex;
  17. int p,i;
  18. table mytable;
  19.  
  20. s = (node*)malloc(sizeof(node)*10);
  21. while(1){
  22. scanf("%d", &datatemp);
  23. if(datatemp<0)
  24. break;
  25. (s+cnt)->data = datatemp;
  26. cnt++;
  27. if(cnt==cntmax){
  28. s = (node*)realloc(s, cntmax+10);
  29. cntmax += 10;
  30. }
  31. }
  32. mytable.list = s;
  33.  
  34. head = 0;
  35. s->next = -1; //-1表示链表表尾结点
  36. //表插入排序
  37. for(k=1; k<cnt; k++){
  38. kk=head;
  39. while(kk!=-1){
  40. if((s+kk)->data>(s+k)->data){
  41. if(kk==head){
  42. head = k;
  43. (s+k)->next = kk;
  44. }
  45. else{
  46. (s+preindex)->next = k;
  47. (s+k)->next = kk;
  48. }
  49. break;
  50. }
  51. else{
  52. preindex = kk;
  53. kk = (s+kk)->next;
  54. }
  55. }
  56. if(kk==-1){
  57. (s+preindex)->next = k;
  58. (s+k)->next = -1;
  59. }
  60. }
  61. mytable.head = head;
  62.  
  63. for(k=mytable.head; k!=-1; k=(mytable.list+k)->next){
  64. printf("%d ", (mytable.list+k)->data);
  65. }
  66. printf("\n");
  67.  
  68. //记录重排-->这里是难点~~
  69. for(i=0, p=head; i<cnt; i++){
  70. //i位置结点与k位置结点交换
  71. while(p<i) //----->注意这里哟,逐个找回来
  72. p = (s+p)->next;
  73. k = (s+p)->next; //保存指向的下一个需要重排的关键字位置
  74.  
  75. if(p!=i){
  76. datatemp = (s+p)->data;
  77. nexttemp = (s+p)->next;
  78. (s+p)->data = (s+i)->data;
  79. (s+p)->next = (s+i)->next;
  80. (s+i)->data = datatemp;
  81. (s+i)->next = p;
  82. }
  83.  
  84. p = k;
  85. }
  86. for(i=0; i<cnt; i++){
  87. printf("%d ", (mytable.list+i)->data);
  88. }
  89. printf("\n");
  90.  
  91. system("pause");
  92. return 0;
  93. }

其他排序请见后篇

【排序】表插入排序算法(C语言版)的更多相关文章

  1. 插入排序---希尔插入排序算法(Javascript版)

    取一个小于n的整数作为第一个增量,把序列分组.所有距离为增量的倍数的元素放在同一个组中.先在各组内进行直接插入排序:然后,取第二个增量(第二个<第一个)重复上述的分组和排序,直至所取的增量=1, ...

  2. 插入排序---直接插入排序算法(Javascript版)

    将n个元素的数列分为已有序和无序两个部分. 数列:{a1,a2,a3,a4,…,an} 将该数列的第一元素视为有序数列,后面都视为无序数列: {{a1},{a2,a3,a4,…,an}} 将无序数列中 ...

  3. 数据结构1:数据结构与算法C语言版分析概述

    本节开始将带领大家系统地学习数据结构,作为一门计算机专业大二学生的必修课程,该课程面对的目标人群为初步具备基本编程能力和编程思想的程序员(大一接触了 C 语言或者 C++).通过系统地学习数据结构,可 ...

  4. 快速排序算法C语言版

    快速排序(Quicksort)是对冒泡排序的一种改进.  快速排序由C. A. R. Hoare在1962年提出.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比 ...

  5. 快速排序的一种实现(Mark Allen 数据结构与算法 c语言版)

    之前关于快速排序一直比较模糊,网上有几种常见写法: 方法一: void quickSort(int s[], int l, int r) { if (l< r) { int i = l, j = ...

  6. 《数据结构与算法(C语言版)》严蔚敏 | 第五章 建立二叉树,并完成三/四种遍历算法

    PS:所有的代码示例使用的都是这个图 2019-10-29 利用p126的算法5.3建立二叉树,并完成三种遍历算法 中序 后序 先序 #include<iostream> #include ...

  7. 插入排序(C语言版)

    #include<iostream>using namespace std;int n;void lan(int a[],int size){ for(int i = 0;i < s ...

  8. 《数据结构与算法(C语言版)》严蔚敏 | 第四章课本案例

    //二叉树的顺序存储表示 #define MAXTSIZE 100 typedef TElemtype SqBiTree[MAXTSIZE]; SqBiTree bt; //二叉树的二叉链表存储表示 ...

  9. 数据结构C语言版 表插入排序 静态表

    数据结构C语言版 表插入排序.txt两个人吵架,先说对不起的人,并不是认输了,并不是原谅了.他只是比对方更珍惜这份感情./*  数据结构C语言版 表插入排序  算法10.3 P267-P270  编译 ...

随机推荐

  1. Tomcat查看用户名密码

    在非安装版的tomcat中,可以在{解压路径}/conf/tomcat_users.xml 配置文件中找到,也可以自己添加新的用户

  2. 【CF689D Friends and Subsequences】二分搜索,区间查询

    题意:给定两个整数序列a,b,将a,b对齐,问有多少个区间满足a的区间内最大值等于b的区间内最小值. 数据范围:区间长度n属于[1, 200000],序列中的元素在整型范围内 思路:枚举所有n*(n+ ...

  3. python学习之路-5 基础进阶篇

    本篇涉及内容 双层装饰器字符串格式化 双层装饰器 装饰器基础请点我 有时候一个功能需要有2次认证的时候就需要用到双层装饰器了,下面我们来通过一个案例详细介绍一下双层装饰器: 执行顺序:自上而下 解释顺 ...

  4. C#~使用FileSystemWatcher来监视文件系统的变化

    对于一个文件夹的改变,C#这边有自己的类来实现,我们不需要关心它的内部实现机制,不需要关心它底层调用哪些API,我们只需要关心如何去调用它,如何让它帮助我们记录文件夹的修改情况即可. #region ...

  5. Android软件开发之常用系统控件界面整理

    1.文本框TextView TextView的作用是用来显示一个文本框,下面我用两种方式为大家呈现TextView, 第一种是通过xml布局文件呈现 ,第二种是通过代码来呈现,由此可见Android ...

  6. BASE64Encoder问题类

    于myeclipse于BASE64Encoder提示类不出现 对当前右击project-->Build Path--->Configure Build Path--->Java Bu ...

  7. Android系统匿名共享内存Ashmem(Anonymous Shared Memory)在进程间共享的原理分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6666491 在前面一篇文章Android系统匿 ...

  8. 用ajaxFileUpLoad上传文件不能正确取得返回值的问题

    刚開始没有认为ajax请求的dataType參数的重要性,用了ajaxFileUpLoad插件后,假设页面代码例如以下: fileElementId : ['imageToUpload'], url ...

  9. ArrayList的分析(转)

    一. ArrayList概述: ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单线程环境 ...

  10. CSU 1808 地铁

    题意: ICPCCamp 有 n 个地铁站,用 1,2,-,n 编号. m 段双向的地铁线路连接 n 个地铁站,其中第 i 段地铁属于 ci 号线,位于站 ai,bi 之间,往返均需要花费 ti 分钟 ...