原题:

双向链表中,需要三个基本数据,一个携带具体数据,一个携带指向上一环节的prev指针,一个携带指向下一环节的next指针。请改写双向链表,仅用一个指针np实现双向链表的功能。定义np为next XOR prev,请根据表头提供的信息,为双向链表编写插入函数、删除函数和查找函数,并在O(1)时间内实现链表的翻转。

分析:

问题的关键,在于怎样利用prev指针和next指针的异或结果,来获得上一节点或下一节点的地址值。也就是说,如何利用异或来算出具体的prev及next值。我们注意到两点:

1、A XOR B = C  =>  C XOR B = A AND C XOR A = B。A、B两个元素的异或结果C,同A异或后得B,同B异或后得A。也就是说,如果我们能获取到next或者prev其中的一个值,我们就能根据np计算出另一个值。

2、双向链表中,头结点的prev值为0,尾结点的next值为0,因此,可以根据这一点,计算出全部的结点prev及next地址。依据第一点,表头信息需要提供头结点的地址。

实现:

C语言中,指针变量中存储的数值不能直接参与异或运算,需要转换为int型变量参与运算,再转换为指针来指定特定的地址。

根据前述分析,定义两个结构体如下:

typedef struct Node

{

int num;

int np;

}Node;

作为结点的结构体,包含结点必须的两个数据:类型为int的num数据单元,和类型为int的np指针,其中np指针中包含了next和prev两个结点的地址。

typedef struct double_train

{

Node *head;

int length;

}double_train;

作为双向链表的表头,提供了链表的大小、头结点两个数据,以供他人操作该链表。

插入函数void Insert(double_train *L , int value):

该函数接受两个参数——链表L和数据value,该函数的功能为将数据value插入表头。具体代码如下:

void

Insert(double_train *L , int value)

{

Node *p = (Node *)malloc(sizeof(Node));

int  temp2;

int  temp1;

p->num = value;

temp2 = (int) L->head;

temp2 = 0 ^ temp2;

p->np = temp2;

//插入一个新节点P,设置prev为0,next为L->head,并表示为np。

if(L->head != NULL)

{

temp1 = (int) p;

temp2 = L->head->np;

L->head->np = temp1 ^ temp2;

}

//若链表非空,则更新原先头结点的np值。

L->head = p;

L->length ++;

}

展示函数 void View(double_train *L):

该函数接受一个参数——链表L,该函数的功能为列出链表L中的所有数据单元。具体代码如下:

void

View(double_train *L)

{

int temp1,Last = 0;

Node *Next;

Node *top = L->head;

int count = L->length;

while(count != 0)        //从头结点开始,根据每个节点的np值遍历链表

{

temp1 = L->head->np ^ Last;

Next = (Node *) temp1;

Last = (int) L->head;

L->head = Next;

count --;

}

L->head = top;

}

删除函数和查找函数代码从略。下面是主函数测试代码,在windows gcc下编译通过并输出正确结果:

int

main(void)             //programmed by wmydx

{

double_train test;

double_train *L = &test;

L->length = 0;

L->head = NULL;  //C并非面向对象,因此不能用构造函数初始化

for(int i = 0;i < 5;i++)

{

Insert(L,i);

}

View(L);

system("pause");

}

那么如何实现在O(1)的时间内对链表进行翻转呢?只需要在链表结构体中加一个记录尾结点 Node *tail的代码,然后exchange tail->np with head->np即可完成。

转载于:https://www.cnblogs.com/shadowmydx/p/4026517.html

【原创】《算法导论》链表一章带星习题试解——附C语言实现相关推荐

  1. 位向量(bit vector)(算法导论第十一章11.1-2)

    位向量(bit vector) 位向量(bit vector)是一个仅包含0和1的数组.长度为m的位向量所占空间要比包含m个指针的数组少得多.说明如何用一个位向量来表示一个包含不同元素(无卫星数据)的 ...

  2. 假设一动态集合S用一个长度为m的直接寻址表T来表示。请给出一个查找S中最大元素的过程。(算法导论第十一章11.1-1)

    假设一动态集合S用一个长度为m的直接寻址表T来表示.请给出一个查找S中最大元素的过程.你所给的过程在最坏情况下的运行时间是多少. (算法导论第十一章11.1-1) #include "Key ...

  3. 算法导论第2章(3) 二分查找 binary search

    二分查找(分治法). 二分查找也是一种分治法的实现,每一次查找将数据分为两个部分,问题规模都减小一半.这样查找的时间复杂度为logN.因为其实查找过程建立了一棵有N个节点的二叉树,查找次数是这棵树的高 ...

  4. 算法图解第六章笔记与习题(广度优先搜索)

    算法图解第六章笔记与习题(广度优先搜索) 文章目录 算法图解第六章笔记与习题(广度优先搜索) 6.1 图(graph) 6.2 广度优先搜索 6.3.1 查找最短路径 6.3.2 队列 6.4 实现图 ...

  5. 算法导论第十三章 红黑树

    写在前面:这一章真的把我害惨了,之前至少尝试看过3遍,每次看之前都下定决定一定要把它拿下,可是由于内容较多,深度够深,以致于每次要不是中途有什么事放弃了就跳过了,要不是花时间太多仍然不能理解而放弃.这 ...

  6. 算法导论 第7章 快速排序 —— 练习还没做,记得补锅

    今天来学习第七章--快速排序. 作为占据一章的排序,快速排序可谓是重量级选手. 实际排序中最好的选择,因为 (1) 其平均性能非常好,期望实践复杂度为 O(n lgn); (2) 可进行原址排序; ( ...

  7. 重读《算法导论》第一章

    重读<算法导论> --------算法是程序的灵魂! 驱动力:本人从事开发10年有余,目前正在参与研发自动化编程.在代码解析.自动生成.以及源码分析过程中总会遇到一些算法的问题. 所以想着 ...

  8. 算法导论第16章练习题 16.1-4

    16.1-4 假设有一组活动,我们需要将它们安排到一些教室,任意活动都可以在任意教室进行.我们希望使用最少的教室来完成活动.设计一个高效的贪心算法,求每个活动应该在哪个教室来进行. (这个问题也被称为 ...

  9. 算法导论第2版-附录课后习题答案

    算法导论-附录A.1-3 对 0<∣x∣<10<|x|<10<∣x∣<1,证明 ∑k=0∞k2xk=x(1+x)/(1−x)3\displaystyle \sum_ ...

  10. 算法导论 第20章 斐波那契堆

    斐波那契堆的定义 参看19章 二项堆我们可以看到对于可合并堆操作,二项堆均有O(lgn)的时间,对于本章将要讨论的斐波那契堆也支持这些操作,而且它有着更好的渐进时间界,对于不涉及元素删除的操作,它有着 ...

最新文章

  1. 通过多说服务器缓存加速Gravatar 头像
  2. 食疗去除头屑的小偏方 不错!
  3. [vue] vue如何优化首页的加载速度?
  4. Objective-C 的OOP(下)-类(static)方法、实例方法、overwrite(覆写)、属性(property)...
  5. 没想到啊!3980元的Web前端视频今日免费送
  6. 指向 类成员函数 指针的用法
  7. python vector变量_用Python实现因子分析
  8. MikroTik RouterOS 3.30 安装+免SSH全自动算号+自动注册L6图文全过程
  9. 【转】C#字符串转换为日期
  10. CocoStudio 简单使用动画
  11. ant design-Table中的分页实现(包括点击跳页,输入跳页,以及指定每页项目数)
  12. arduino无线下载
  13. Yandex插件使用说明——Slager_Z
  14. python操作模拟器多开操作_窗口多开模拟器同步操作器▲按键精灵脚本▲
  15. 揭秘Apple Watch心率监测技术
  16. 我在富士康挨踢了七年(十三.悉尼工作篇 )
  17. oracle的floor用法,oracle ceil floor 函数的用法
  18. 群赛14----2017.9.24
  19. 图片文字识别的方法有哪些?
  20. VB-改变文件只读属性

热门文章

  1. GitHub遭遇史上最强DDoS攻击:峰值流量1.35Tbps!
  2. 教你分分钟学会用python爬虫框架Scrapy爬取心目中的女神
  3. 实验五 编写、调试具有多个段的程序
  4. XMLConfigBuilder文件
  5. 表格 滚动条 (tbody部分滚动)
  6. JSP内置对象之application
  7. python的N个小功能(图片预处理:打开图片,滤波器,增强,灰度图转换,去噪,二值化,切割,保存)...
  8. 课后作业-阅读任务-阅读笔记3
  9. 解决Robot Framework运行时没有Log的方案
  10. iOS 微信消息拦截插件系列教程-附录(服务端成果展示)