2.3

pre

typedef struct Lnode{ElemType data;struct Lnode *next;
}LNode,*LinkList;
typedef struct DNode{ElemType data;struct DNode *prior,*next;
}DNode, *DLinklist;

2.3.02

在带头结点的单链表L中,删除所有值为x的结点,并释放其空间,假设值为x的结点不唯一,试编写算法以实现上述操作。

void del_x(LinkList &L, ElemType x)
{LNode *p = L->next, *pre = L, *q;//q是临时节点,好像就要用指针while(p!=NULL){if(p->data == x){q = p;p = p->next;pre->next = p;free(q);}else{pre = p;p = p->next;}//else}//while
}

2.3.03

设L为带头结点的单链表,编写算法实现从尾到头反向输出每个结点的值

void print_r(LinkList &L)
{if(L->next!=NULL) print_r(L->next);if(L!=NULL) printf("%d",L->data);
}
void reverse(LinkList &L)
{if(L!=NULL) print_r(L);return;
}

2.3.05

试编写算法将带头结点的单链表就地逆置,也就是空间复杂度为O(1)

//解法一,拆下来以后用头插法反插
LinkList reverse(LinkList &L)
{LNode *p,*r,*pre;p = L->next;L->next=NULL;while(p->next!=NULL){q = p->next;p->next = L->next;L->next = p;p = q;}return L;
}
//解法二,反向插,最后将位置指向L,两个时间复杂度都是O(n),空间复杂度为O(1)
LinkList reverse(LinkList &L)
{LNode *p,*r,*pre;p = L->next; r = p->next; p->next = NULL; while(r!=NULL){pre = r->next;r->next = p;p = r;r = pre;}   L->next = p;return L;
}

2.3.08

给定两个单链表,编写算法找出两个链表的公共结点

分析:如果存在公共结点,那两个链表的结尾都是相同的,所以可以先计算两个链表的长度,再减去插值寻找公共结点,时间复杂度为O(length1+length2)

LinkList find_1st(LinkList &L1, LinkList &L2)
{int len1 = Length(L1), len2 = Length(L2);int dist;LinkList p,q;if(len1>len2){p = L1->next; q = L2->next;dist = len1-len2;}else{p = L2->next; q = L1->next;dist = len2-len1;}while(dist--){p = p->next;}while(p!=NULL){if(p==q)//真的可以这么写吗?return p;else{p = p->next;q = q->next;}}return NULL;
}

2.3.11

将一个带头结点的单链表A分解为两个带头结点的单链表B和C,使得B表中含有原表中序号为奇数的元素,而C表中含有原表中序号为偶数的元素,且C表中顺序反过来,并保持相对顺序

思路:没啥区别,练练链表的手。有个很有意思的地方,就是这个怎么返回两个链表的同时读入一个链表,答案的做法是保留原来输入的链表作为其中一个结果进行输出,另一个用函数返回值进行返回。

LinkList divide(LinkList &A )
{LinkList B = (LinkList)malloc(sizeof(LNode));B->next = NULL;LNode *p=A->next, *q;LNode *tmp = A;//指向A的尾结点while(p!=NULL){tmp->next = p; tmp = p;p = p->next;if(p!=NULL){q = p->next;p->next = B->next;B->next = p;p = q;}}tmp->next = NULL;return B;
}
LinkList divide_myself(LinkList &A)
{LinkList B = (LinkList)malloc(sizeof(LNode));B->next = NULL;LNode *pr = A;LNode *cr = A->next;while(cr!=NULL){cr = cr->next;pr = pr->next;if(cr!=NULL){pre->next = cr->next;cr->next = B->next;B->next = cr->next;cr = pre->next;}}cr->next =NULL;//如果是奇数的情况下进行的定义return B;
}

2.3.16

两个整数序列A=a1,a2,…,am和B=b1,b2,…,bn已经存入两个单链表中,设计一个算法判断B是否是A的连续子序列

int child_series(LinkList &A, LinkList &B)
{LNode *a = A, *b = B;LNode *p = a;//用于存档while(a&&b){if(a->data == b->data){a = a->next;b = b->next;}else{b = B;//回到表头p = p->next;a = p;}   }//whileif(b == NULL) return 1;else return 0;
}

2.3.20

设头指针为L的带有表头结点的非循环双向链表,其每个结点中除有prior(前驱指针),data(数据)和next(后继指针)域外,还有一个访问频度域freq.在链表被启用前,其值均初始化为零,每当在链表中进行一次Locate(L,x)运算时,令元素值为x的结点中freq域的值增1,并使此链表中结点保持按访问频度非增(递减)的顺序排列,同时最近访问的结点排在频度相同的结点前面,以便使频繁访问的结点总是靠近表头.试编写符合上述要求的Locate(L,x)运算的算法,该运算为函数过程,返回找到结点的地址,类型为指针型.

void Locate(LinkList &L, ElemType x)
{LNode *s = L;LNode *sr = L, tmp;while(s!=NULL){if(s->data != x) s = s->next;else s->freq++;}if(s==NULL)//not foundreturn -1;else//change the place{ while(sr->freq>s->freq&&sr!=NULL) sr = sr->next;if(sr!=NULL){//exist prior places->pred->next = s->next;s->next->pred = s->pred;sr->pred->next = s;s->pred = sr->pred; s->next = sr;sr->pred = s;}// end if}//end else
}
//也可以考虑从s开始往前遍历,这样的效率更高但是我不想再写一版了。

2.3.22

已知一个带有表头结点的单链表,结点结构为 data link 假设该链表只给出了头指针list。在不改变链表的前提下,请设计一个尽可能高效的 算法,查找链表中倒数第k个位置,如果成功则输出该点的data域的值,并返回1,否则返回0

  1. 基本思路

    直接取两个节点,一个在后面k个位置,后面那个到NULL了前面那个刚好再倒数第k个位置。

  2. 代码

int find_reverse_k(int k, LinkList &L)
{LNode *pre = L, *lat = L;for(int i = 0; i<k; i++){lat = lat->next;if(lat == NULL) return 0;}while(lat!=NULL){lat = lat->next;pre = pre->next;}printf("%d",pre->data);return 1;
}

2.3.25

设线性表L=(a1,a2,a3,…,an-2,an-1,an),采用带头节点的单链表保存。设计算法,重新排列L中的节点,得到线性表L’=(a1,an,a2,an-1,a3,an-2,…)。

  1. 思路

    我想的是先建立头结点,然后先用尾插法把后半部分给插上,再正向进行一个隔一个的差。这样的时间复杂度是O(n),空间复杂度是O(1)

  2. (typora的换行真的是一坨沈阳美食家)代码

LinkList reshape(LinkList &L)
{LinkList B = (LinkList)malloc(sizeof(LNode));LNode *tmp;B->next = NULL;LNode *mid=L->next, *fin=L->next;int length=0;//the length of line//first find the mid placewhile(fin!=NULL){mid = mid->next;fin = fin->next;if(fin!=NULL){fin = fin->next;length+=2;}else length+=1;}// mid is deemed to be the later part and without the mid pointwhile(mid!=NULL){tmp = mid;mid->next = B->next;B->next = mid;mid = tmp->next;}// after this, it is (an,an-1,...a(n/2))tmp = L->next; fin = tmp->next; mid = B;for(i = 0; i<(length+1)/2; i++){tmp->next = mid->next;mid->next = tmp;mid = mid->next->next;tmp = fin;fin = fin->next;}return B;
}
//当然,也可以像答案那样直接把后半部分进行逆置,然后前后加,也可以得到一样的结果
void change_list(Node *h)
{Node *p,*q,*r,*s;p = q = h;while(q->next != NULL){p = p->next;q = q->next;if(q->next != NULL) q = q->next;}q = p->next;//p所指节点为中间节点,q为后半段链表的首节点,我的做法提前next了,所以不一样p->next = NULL;while(q!=NULL){//将链表后半段逆置r = q->next;q->next = p->next;p->next = q;q = r;}s = h->next;q = p->next;p->next = NULL;while(q!=NULL){r = q->next;q->next = s->next;s->next =q;s = q->next;q = r;}
}

后记

链表有点难,但是很suang口,写到后面还是有点high的

王道考研408 数据结构 2.3 链表练习题相关推荐

  1. 【专栏必读】王道考研408数据结构万字笔记(有了它不需要你再做笔记了):各章节内容概述导航和思维导图

    其他科目导航 [专栏必读]王道考研408计算机组成原理万字笔记(从学生角度辅助大家理解):各章节导航及思维导图 [专栏必读]王道考研408操作系统万字笔记(从学生角度辅助大家理解):各章节导航及思维导 ...

  2. 一篇学完:王道考研408数据结构(全)

    笔记首发于:lengyueling.cn PDF版本附在 lengyueling.cn 对应文章结尾,欢迎下载访问交流 绪论 数据结构在学什么 如何用程序代码把现实世界的问题信息化 如何用计算机高效地 ...

  3. 王道考研408 数据结构 第三章 栈、队列与数组

    第三章 栈.队列与数组 3.1 栈 3.1.03 假设以I和O分别表示入栈和出栈操作.栈的初态和终态均为空,入栈和出栈的操作序列可表示为仅由I和O组成的序列,称可以操作的序列为合法序列,否则称为非法序 ...

  4. 【专栏必读】王道考研408操作系统万字笔记(从学生角度辅助大家理解):各章节导航及思维导图

    其他科目导航 [专栏必读]王道考研408计算机组成原理万字笔记(从学生角度辅助大家理解):各章节导航及思维导图 [专栏必读]王道考研408数据结构万字笔记(有了它不需要你再做笔记了):各章节内容概述导 ...

  5. 【专栏必读】王道考研408计算机组成原理万字笔记和题目题型总结(从学生角度辅助大家理解):各章节导航及思维导图

    其他科目导航 [专栏必读]王道考研408操作系统万字笔记(有了它不需要你再做笔记了):各章节内容概述导航和思维导图 [专栏必读]王道考研408数据结构万字笔记(有了它不需要你再做笔记了):各章节内容概 ...

  6. 【专栏必读】王道考研408计算机组成原理万字笔记、题目题型总结、注意事项、目录导航和思维导图

    王道考研复习指导下载(密码7281) 其他科目导航 [专栏必读]王道考研408操作系统万字笔记(有了它不需要你再做笔记了):各章节内容概述导航和思维导图 [专栏必读]王道考研408数据结构万字笔记(有 ...

  7. 【专栏必读】王道考研408计算机网络+湖科大教书匠计算机网络+网络编程万字笔记、题目题型总结、注意事项、目录导航和思维导图

    王道考研复习指导下载(密码7281) 其他科目导航 [专栏必读]王道考研408计算机组成原理万字笔记(从学生角度辅助大家理解):各章节导航及思维导图 [专栏必读]王道考研408操作系统万字笔记.题目题 ...

  8. 王道考研2021——数据结构学习笔记

    王道给的代码中,有些用的是c++,但是和c的区别不大,不影响理解. ElemType e 指e为任意数据类型,如struct,int- 文章目录 线性表 顺序表 定义 静态分配 动态分配 初始化与增加 ...

  9. 2022王道考研有关数据结构笔记

    第二章 线性表 2.1 线性表的定义和基本操作 要点: 线性表的基本操作--创销.增删.改查 传入参数时,何时要用引用 & 2.2 线性表的顺序表示 2.2.1 顺序表的定义 顺序表的实现-- ...

最新文章

  1. 【免费福利】零AI基础,如何搭建聊天机器人:技术架构剖析
  2. 【敏捷测试】一个测试人员在参与敏捷测试的经验分享(3)
  3. H5 移动端 获取腾讯地图计算两经纬度的实际距离(可批量)_多地打卡
  4. C++将地址转换为字符串
  5. 5799元!OPPO Find X5 Pro天玑版即将开卖:性能比肩骁龙8
  6. 线性代数 n维向量思维导图总结(看这一张就完事了)
  7. c语言中等于号和大于号的优先级,C  读书笔记之 关系运算符重载 大于号 小于号  等于号==...
  8. [ffmpeg][goav]ffmpeg代码例子pcmu重采样并转码aac格式
  9. taskmgr跟着敲
  10. 内网穿透远程查看内网监控摄像头
  11. 基于TBSS的DTI数据处理流程
  12. Android 升级/刷机攻略(Google原生系统Pixel)
  13. 自动驾驶技术(2)--智能车辆导航技术概述
  14. 某音xg加密算法研究
  15. 戴尔台式计算机怎么拆卸两块侧板,高效易用 戴尔OptiPlex 7050商用台式机评测
  16. Js逆向案例—网易云音乐
  17. vuecli4安装axios以及简单使用
  18. [PC] 2004 忍者神龟2:并肩作战 Teenage Mutant Ninja Turtles2:Battle Nexus
  19. UI设计中Sketch使用指南—入门篇
  20. 2023Facebook该如何养号?Facebook防封指南了解一下!

热门文章

  1. 数据段、代码段、BSS段、堆栈段
  2. Android 读取string.xml到EXCEL表格
  3. 16进制字符串与JPG图片互转
  4. TP5中Session
  5. https - nginx反向代理 - nginx端口映射
  6. ubuntu实时监测显卡使用信息
  7. 今天写出来了九九乘法表,好开心啊!!!!
  8. Properties介绍与使用
  9. 没有人工智能就没有ChatGPT,人工智能有哪些社会价值?
  10. Java中nextInt()和nextLine()混用问题解决