在前一篇插入排序:表插入中。我们用静态链表的存储方式。直接插入的策略,构建了一种新的插入排序算法:表插入。

有人可能会想到:相同是静态链表的形式,为什么不使用更高效的折半插入策略呢?这样的想法真的非常好,假设做到了。显然是极大的优化。

我在网上还真看到了相关的内容,大家可搜下《表插入方法的改进》,里面有此想法的介绍。这篇博客就是介绍表插入的还有一种实现:表折半插入。看完一定让你彻底理解它!

与一般的折半插入相比,有例如以下的几点变化:

  1. 为了实现折半查找,我们对静态链表的节点类型做了一些变化:加入了一个前驱指针。

    它的意义非常显然,曾经是high=mid-1,在单向链表中我们是做不到的(事实上能够换种方式做到,只是相对麻烦),于是加入一指向其前驱的指针。构成双向链表,方便进行此操作。

  2. while循环的结束条件,有所不同。这个要细致理解!
其它细节,代码中有详解
const int MAX=100;
typedef struct rec
{int data;int pre;   //前驱 int next;  //后继
}Rec;
void InsertSort(int a[], int n)  //表折半插入
{Rec *rec=new Rec[n+1];for(int i=0; i<n; i++){rec[i+1].data=a[i];rec[i+1].next=rec[i+1].pre=0;}rec[0].data=MAX;rec[0].next=rec[0].pre=1;int low,high,mid;int p,k,l;for(int i=2; i<n+1; i++){//依据下面的赋值,我们能够看出。这里使用的是左闭右闭区间 low=rec[0].next;    //low指向最小的 high=rec[0].pre;    //high指向最大的 l=i-1;      //已有序的元素个数 while(low!=0 && high!=0 && rec[low].data<=rec[high].data)  //循环结束条件得理解,特别是前两个条件。

准确的是。第一个条件能够不要 { mid=low; k=1; l/=2; // l>>=2 减半。为下次循环做好准备 while(k<l) //寻找mid位置 { mid=rec[mid].next; k++; } if(rec[i].data<rec[mid].data) high=rec[mid].pre; else low=rec[mid].next; } //插入第i个节点。相似于双向链表的插入 rec[rec[low].pre].next=i; rec[i].pre=rec[low].pre; //加入前驱指针的作用体如今这里 rec[i].next=low; rec[low].pre=i; } //顺着next指针方向打印 printf("表折半插入排序后\n"); p=rec[0].next; while(p!=0) { printf("%-4d",rec[p].data); p=rec[p].next; } printf("\n"); }

细致看完代码,我想大多数人仅仅剩一个问题可能没明确,那就是while循环的结束条件为什么还得加上low!=0high!=0
为了解释清楚。我们画一个图,图中正在插入i=2的节点:
初始化后。low,mid,high显然都指向1,经过下一步rec[i].data与rec[mid].data比較后,不管结果如何,循环都应结束。

可假设

rec[i].data<rec[mid].data,就有high=rec[mid].pre,即high=1.此时显然有rec[low]<rec[high],也就是说循环还得接着经进行下去。问题就出在这里!讲到这里,你应该明确:即使出现low为0,它也会违反第三条件:rec[low].data<=rec[high].data)(由于rec[0]的值域是最大的)。这就是为什么说,第一个条件low!=0能够去掉。

到此。你应该明确了代码中全部的凝视。
測试走起啊……
p.s 对rec数组1-n号元素进行重排也是能够的,做法參照上一篇博客哦,方法一模一样。
转载请注明出处,本文地址:http://blog.csdn.net/zhangxiangdavaid/article/details/28635157
若是写得好。顶一个哦。
代码就是折腾,越折腾越进步!
专栏文件夹看这里:
  • 数据结构与算法文件夹
  • c指针

插入排序:表折半插入相关推荐

  1. 插入排序:直接插入、交换插入、折半插入

    插入排序:把一个数插入到一个有序的序列中,并要求插入后此数据序列仍然有序.这种排序思想就是插入排序. 那么对于一个原始无序的序列,哪里找有序的部分呢?这个很简单,可以把序列分为两个部分,第一个元素是第 ...

  2. C语言——十四种内部排序算法【直接插入排序-冒泡排序-选择排序-插入排序-希尔排序-归并排序-快速排序-堆排序-折半插入排序-二分查找-路插入排序-表插入排序-简单选择排序-直接选择排序-树形选择】

    目录: 一:插入排序 A:直接插入排序 1.定义: 2.算法演示 实例1: 3.基本思想 4.排序流程图 实例1: B:希尔排序 1.定义: 2.算法演示 实例2: C:其他插入排序 a:折半插入排序 ...

  3. (1.3.3)插入排序:直接插入、交换插入、折半插入

    插入排序:把一个数插入到一个有序的序列中,并要求插入后此数据序列仍然有序.这种排序思想就是插入排序. 那么对于一个原始无序的序列,哪里找有序的部分呢?这个很简单,可以把序列分为两个部分,第一个元素是第 ...

  4. 折半查找和线性表的插入与删除实验

    学号                     姓名                   博客名 2103101018         罗玛                   桃花岛-戌时 题目:折半 ...

  5. C语言基本数据结构之五(折半插入,堆排序,冒泡排序,快速排序,并归排序)

    上一篇大概写了序列的查找算法,这次就聊聊序列的几种重要的排序(大神自动飘过~~~) 一.算法分析 1.1 直接插入排序 基本思想:将文件中的记录分为有序区.无序区,不断地从无序区中顺序提取记录,按关键 ...

  6. 直接插入排序以及折半插入排序详解

    一.直接插入排序 每次将一个待排序的序列插入到一个前面已排好序的子序列当中 使用到了顺序查找 图片演示 前面是有序的,逐步逐步将后面的插入到前面去 实现步骤 初始L[1]L[1]L[1] 是一个已经排 ...

  7. 排序算法java版,速度排行:冒泡排序、简单选择排序、直接插入排序、折半插入排序、希尔排序、堆排序、归并排序、快速排序...

    先推荐一篇关于排序算法的文章:http://www.cppblog.com/guogangj/archive/2009/11/13/100876.html 本文思路部分来源于上篇文章,但测得的结果似乎 ...

  8. 三种插入排序算法:直接插入排序、折半插入排序、希尔插入排序

    一.直接插入排序 空间复杂度:O(1) 时间复杂度:O(n^2) 稳定性:稳定 适用性:顺序表和链表 //直接插入排序 void InsertSort1(int A[],int n){int i,j, ...

  9. 排序算法(一)--插入排序法折半插入排序法

    约定: 假设数据中有n个数据元素(关键字).排列算法中,将序列中各关键字值依次存放于类型为keytype的数组元素K[1], K[2], K[3], -, K[n]中. 排序结果按照数据元素(关键字) ...

最新文章

  1. poj3122(二分算法)
  2. “计算社会科学数据平台”在清华大学发布(附账号申请链接)
  3. ASP.NET连接带密码Access的方法
  4. .net托管环境下struct实例字段的内存布局(Layout)和大小(Size)
  5. 从零入门 Serverless | Serverless 应用如何管理日志 持久化数据
  6. 先定个小目标, 使用C# 开发的千万级应用
  7. 学习笔记之数据可视化(一)——项目适配方案
  8. 使用explain查询select查询语句执行计划
  9. 9款极具创意的HTML5/CSS3进度条动画
  10. 怎么做应力应变曲线_做了这么多年材料,这些力学性能测试你做对了吗?
  11. WSUS服务器更改存放路径方法
  12. 物联网时代的技术迷雾
  13. 数据库mysql基本查询语句_数据库mysql基础查询语句实录
  14. 3D元素周期表源码(已加注释)及分析
  15. 宝塔面板+小鸟云服务器安全设置
  16. 零基础语法入门第九/十讲 使用疑问词进行提问和回答
  17. 微信网页/微信小程序内实现长按识别二维码
  18. linux怎么编译ipa,如何使用XCode 4创建ipa文件及提交应用程序
  19. exchange 网页无法连接服务器,exchange2016 无法连接服务器
  20. iPad----------教你如何查询ipad型号

热门文章

  1. java.lang.ClassNotFoundException: org.springframework.web.util.IntrospectorCleanupListener
  2. JAVA随机生成文件名:当前年月日时分秒+五位随机数
  3. leetcode239. 滑动窗口最大值
  4. leetcode129. 求根到叶子节点数字之和
  5. 关系数据库——sql增删改
  6. C++:39---继承中构造函数、析构函数的关系
  7. java控制面板作用_Java
  8. C++ 标准程序库std::string 详解
  9. 对于以太坊的Solidity语言介绍
  10. FLV文件格式(Z)(转载)