严蔚敏《数据结构》习题(二)
严蔚敏《数据结构》习题(二)
2.38 设有一个双向循环链表,每个结点中除有pre,data和next三个域外,还增设了一个访问频度域freq。在链表被起用之前,频度域freq的值均初始化为零,而每当对链表进行一次LOCATE(L,x)的操作后,被访问的结点(即元素值等于x的结点)中的频度域freq的值便增1,同时调整链表中结点之间的次序,使其按访问频度非递增的次序顺序排列,以便始终保持被频繁访问的结点总是靠近表头结点。试编写符合上述要求的LOCATE操作的算法。
Status LOCATE(DuLinkList &L,int x){//每进行一次操作,被访问的结点freq值加1,同时调整结点次序,使其按freq值非递增排列DuLinkList p,q; if(!L) return ERROR;p = L->next;q = L->next;while(p != L && p->data != x)//遍历找数p = p->next;if(p == L) return FALSE; //表中无此数p->freq++; //频数+1p->pre->next = p->next;p->next->pre = p->pre; //先删除p结点while(q != L && q->freq >= p->freq)q = q->next; //辅助指针定位到插入位if(q == L){p->next = q->next;q->next = p;p->pre = q->pre;q->pre = p;}//频数最小为0,所以q总是能找到插入位,如果q循环到头结点,表明原表只剩头结点else{p->next = q->pre->next;q->pre->next = p;p->pre = q->pre;q->pre = p;}//其余情况正常插入return OK;
}
完整C实现:
#include<stdio.h>
#include<malloc.h>
#define OK 1
#define ERROR 0
#define FALSE 0
typedef int Status;typedef struct DuLNode{ int data;//假设data为整型int freq;struct DuLNode *pre;struct DuLNode *next;
}DuLNode,*DuLinkList;Status InitDuList(DuLinkList &L){//初始化双向循环链表L = (DuLinkList)malloc(sizeof(DuLNode)); L->next = L; L->pre = L;
}Status InsertDuList(DuLinkList &L){//插入DuLinkList q=L,p;int n,i = 1,f = 0;printf("请输入结点个数:");scanf("%d",&n);while(n--){p = (DuLinkList)malloc(sizeof(DuLNode));if(!p) return ERROR;printf("请输入第%d个结点值:",i++);scanf("%d",&p->data);p->next = q->pre->next;q->pre->next = p;p->pre = q->pre;q->pre = p;q = L;if(!f++) q->next = p;//循环}
}Status PrintDuList(DuLinkList L){//遍历打印DuLinkList p = L->next; while(p != L){ printf("%d ",p->data); p = p->next; } printf("\n");
}Status LOCATE(DuLinkList &L,int x){ DuLinkList p,q; if(!L) return ERROR;p = L->next;q = L->next;while(p != L && p->data != x)//遍历找数p = p->next;if(p == L) return FALSE;//表中无此数p->freq++;p->pre->next = p->next;p->next->pre = p->pre; //先删除p结点while(q != L && q->freq >= p->freq)q = q->next;if(q == L){p->next = q->next;q->next = p;p->pre = q->pre;q->pre = p;}else{p->next = q->pre->next;q->pre->next = p;p->pre = q->pre;q->pre = p;}return OK;
}int main(){ DuLinkList L;int x; InitDuList(L); InsertDuList(L); do{printf("序列为:"); PrintDuList(L);printf("请输入要访问的值,111结束:");scanf("%d",&x);LOCATE(L,x);}while(x!=111);return 0;
}
3.15 假设以顺序存储结构实现一个双向栈,即在一维数组的存储空间中存在着两个栈,它们的栈底分别设在数组的的两个端点。试编写实现这个双向栈tws的三个操作:初始化inistack(tws),入栈push(tws,i,x)和出栈pop(tws,i)的算法,其中i为0或1,用以分别指示设在数组两端的两个栈,并讨论按过程(正/误状态变量可设为变参)或函数设计这些操作算法各有什么优缺点。
#define STACK_INIT_SIZE 100
typedef struct{int top[2];int base[2];SElemType s[STACK_INIT_SIZE];
}TwsStack;Status Inistack(TwsStack &tws){//初始化双向栈,base指向数组两侧不可取的位置tws.base[0] = tws.top[0] = -1;tws.base[1] = tws.top[1] = STACK_INIT_SIZE;return OK;
}Status Push(TwsStack &tws,int i,SElemType e){//入栈if(tws.top[0] + 1 == tws.top[1]) return ERROR;//栈满if(i) tws.top[1]--;else tws.top[0]++;tws.s[tws.top[i]] = e;return OK;
}Status Pop(TwsStack &tws,int i,SElemType &e){//出栈,为方便调试,增加参数e返回出栈元素if(i){if(tws.top[1] == tws.base[1]) return ERROR;//栈空e = tws.s[tws.top[1]];(tws.top[1]++) == NULL;}else{if(tws.top[0] == tws.base[0]) return ERROR;//栈空e = tws.s[tws.top[0]];(tws.top[0]--) == NULL;}return OK;
}
完整C实现:
#include<stdio.h>#define STACK_INIT_SIZE 100
#define OK 1
#define ERROR 0
typedef int Status;
typedef struct{int top[2];int base[2];int s[STACK_INIT_SIZE];
}TwsStack;Status Inistack(TwsStack &tws){//初始化双向栈,base指向数组两侧不可取的位置tws.base[0] = tws.top[0] = -1;tws.base[1] = tws.top[1] = STACK_INIT_SIZE;return OK;
}Status Push(TwsStack &tws,int i,int e){//入栈if(tws.top[0] + 1 == tws.top[1])//栈满return ERROR;if(i) tws.top[1]--;else tws.top[0]++;tws.s[tws.top[i]] = e;return OK;
}Status Pop(TwsStack &tws,int i,int &e){//出栈if(i){if(tws.top[1] == tws.base[1])//栈空return ERROR;e = tws.s[tws.top[1]];(tws.top[1]++) == NULL;}else{if(tws.top[0] == tws.base[0])//栈空return ERROR;e = tws.s[tws.top[0]];(tws.top[0]--) == NULL;}return OK;
}int main(){TwsStack tws; int i,e = 1,f;Inistack(tws);printf("请输入0号栈元素:\n");scanf("%d",&e);while(e != 111){Push(tws,0,e);scanf("%d",&e);}e = 1;printf("请输入1号栈元素:\n");scanf("%d",&e);while(e != 111){Push(tws,1,e);scanf("%d",&e);}printf("0号栈出栈:\n");while(tws.top[0] != tws.base[0]){Pop(tws,0,f);printf("%d ",f);}printf("\n");printf("1号栈出栈:\n");while(tws.top[1] != tws.base[1]){Pop(tws,1,f);printf("%d ",f);}return 0;
}
3.19 假设一个算术表达式中可以包含三种括号:圆括号“(”和“)”、方括号“[”和“]”和花括号“{”和“}”,且这三种括号可按任意的次序嵌套使用(如:…[…{…}…[…]…]…[…]…(…)…)。编写判别给定表达式中所含括号是否正确配对出现的算法(已知表达式已存入数据元素为字符的顺序表中)。
Status MatchStack(Stack S,SqList L){//括号匹配函数,元素已存入字符顺序表。TRUE为匹配,FALSE为不匹配int i = 0;char e;if(L.length <= 0) return ERROR;while(i < L.length){if(L.elem[i] == '('||L.elem[i] == '['||L.elem[i] == '{')//左括号入栈Push(S,L.elem[i]);else if(L.elem[i] == ')'||L.elem[i] == ']'||L.elem[i] == '}'){if(S.top == S.base) return FALSE;//出现右括号但栈空,不匹配Pop(S,e);//出栈比对switch(L.elem[i]){case ')':if(e != '(') return FALSE; break;case ']':if(e != '[') return FALSE; break;case '}':if(e != '{') return FALSE; break;default:break;} }i++;}if(S.top != S.base) return FALSE;//左括号剩余,不匹配return TRUE;
}
完整C实现:
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define FALSE 0
#define TRUE 1
#define OVERFLOW -2
#define LIST_INIT_SIZE 100 //初始分配容量
#define LISTINCREMENT 10 //分配增量
#define STACK_INIT_SIZE 100 //初始分配容量
#define STACKINCREMENT 10 //分配增量
typedef int Status;typedef struct{char *elem; //存储空间基址int length; //当前长度int listsize; //当前分配容量
}SqList;typedef struct{char *top;char *base;int stacksize;
}Stack;Status InitList(SqList &L){//建表 L.elem = (char*)malloc(LIST_INIT_SIZE*sizeof(char));if(!L.elem){printf("建表出错\n");exit(OVERFLOW);}L.length = 0;L.listsize = LIST_INIT_SIZE;return OK;
} Status InputList(SqList &L,int n){//输入 int i;if(n < 1 || n > L.listsize){printf("输入出错\n");return ERROR;}printf("请输入元素:\n");getchar();for(i = 0;i < n;i++) scanf("%c",&L.elem[i]);L.length = n;return OK;
}Status OutputList(SqList L,int n){//输出 int i;if(n < 1 || n > L.listsize) return ERROR;if(L.length == 0) return ERROR;printf("元素为:");for(i = 0;i < n;i++)printf("%c ",L.elem[i]);return OK;
}Status InitStack(Stack &S){//操作数栈 S.base=(char *)malloc(STACK_INIT_SIZE*sizeof(char));if(!S.base){ //存储分配失败printf("分配空间时出错。\n");exit(OVERFLOW); } S.top = S.base; //初始化指针 S.stacksize = STACK_INIT_SIZE;
}Status Push(Stack &S,char e){if(S.top - S.base >= S.stacksize){S.base=(char *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(char));if(!S.base){ printf("追加空间时出错。\n");exit(OVERFLOW);}S.top = S.base + S.stacksize;S.stacksize += STACKINCREMENT;}*S.top++ = e;
}Status Pop(Stack &S,char &e){//出栈 if(S.top == S.base){printf("出栈时出错。\n"); return ERROR;}e = *--S.top;
}Status MatchStack(Stack S,SqList L){int i = 0;char e;if(L.length <= 0) return ERROR;while(i < L.length){if(L.elem[i] == '('||L.elem[i] == '['||L.elem[i] == '{')Push(S,L.elem[i]);else if(L.elem[i] == ')'||L.elem[i] == ']'||L.elem[i] == '}'){if(S.top == S.base) return FALSE;//不匹配Pop(S,e);switch(L.elem[i]){case ')':if(e != '(') return FALSE; break;case ']':if(e != '[') return FALSE; break;case '}':if(e != '{') return FALSE; break;default:break;} }i++;}if(S.top != S.base) return FALSE;return TRUE;
}int main(){Stack S;SqList L;int n; InitStack(S);InitList(L);printf("请输入元素个数:");scanf("%d",&n); InputList(L,n);OutputList(L,n); if(MatchStack(S,L)==1)printf("括号匹配");else printf("括号不匹配");return 0;
}
3.27 已知Ackerman函数的定义如下:
akm(m,n)={n+1m=0akm(m−1,1)m≠0,n=0akm(m−1,akm(m,n−1))m≠0,n≠0akm(m,n)=\left\{ \begin{aligned} n+1&& m=0 \\ akm(m-1,1) && m\not=0,n=0\\ akm(m-1,akm(m,n-1)) && m\not=0,n\not=0 \end{aligned} \right. akm(m,n)=⎩⎪⎨⎪⎧n+1akm(m−1,1)akm(m−1,akm(m,n−1))m=0m=0,n=0m=0,n=0
(1)写出递归算法;
(2)根据递归算法,画出求akm(2,1)时栈的变化过程。
(1)
Status Ackerman(int m,int n){if(m == 0) return (n + 1);else if(n == 0) return Ackerman(m - 1,n);else return Ackerman(m - 1,Ackerman(m,n - 1));
}
(2)
3.29 如果希望循环队列中的元素都能得到利用,则需设置一个标志域tag,并以tag的值为0或1来区分,尾指针和头指针值相同时的队列状态是“空”还是“满”。试编写与此结构相应的入队列和出队列的算法,并从时间和空间角度讨论设标志和不设标志这两种方法的使用范围(如当循环队列容量较小而队列中每个元素占的空间较多时,哪一种方法较好)。
Status EnQueue(Queue &Q,QElemType e){//入队if(Q.front == Q.rear && Q.tag == 1) return ERROR;//队满Q.base[Q.rear] == e;Q.rear = (Q.rear + 1) % MAXQSIZE;if(Q.front == Q.rear) Q.tag = 1;return OK;
}Status DeQueue(Queue &Q,QElemType &e){//出队if(Q.front == Q.rear && Q.tag == 0) return ERROR;//队空e = Q.base[Q.rear];Q.front = (Q.front + 1) % MAXQSIZE;if(Q.front == Q.rear) Q.tag = 0;return OK;
}
当循环队列容量较小而队列中每个元素占的空间较多时,用tag表示可以节省更多存储空间,但也因为tag的关系,运行时间相应变长。
严蔚敏《数据结构》习题(二)相关推荐
- 严蔚敏数据结构习题第六章
https://www.cnblogs.com/kangjianwei101/p/5243404.html 目录 36-47 二叉树 6.3,6.5,6.6,6.10,6.13,6.14,6.19,6 ...
- 严蔚敏数据结构习题第九章
l第九章查找作业题目9.9 9.14 9.19 9.25 9.31 9.33,平台提交入口已开通,截止日期6月20日 https://www.cnblogs.com/kangjianwei101/p/ ...
- 严蔚敏数据结构源码及习题解析
⭐ 我的网站: www.mengyingjie.com ⭐ 严蔚敏数据结构源码及习题解析 习题解析未更新完整,以后更新 内容已上传到github,欢迎star和fork: https://github ...
- KMP算法-严蔚敏数据结构
KMP 算法是 D.E.Knuth.J,H,Morris 和 V.R.Pratt 三位神人共同提出的,称之为 Knuth-Morria-Pratt 算法,简称 KMP 算法.该算法相对于 Brute- ...
- 严蔚敏数据结构C语言版——线性表的链式存储方式详细代码
一.严蔚敏数据结构C语言版 由于书上的许多地方都是伪代码,所以下面的代码对课本上的做了一些改动,使代码能够正常运行 链表的定义即相关类型定义 typedef int ElementType; type ...
- 严蔚敏数据结构c++版微盘_数据结构复习知识点总结
<数据结构>重点在线性表.树.图.查找和排序.参考书目是<数据结构>(C语言版)严蔚敏.吴伟民编著.通过对线性表.队列.栈和数组的了解,进一步理解其含义,熟悉各种例如进栈.出栈 ...
- 2021-10-16【严蔚敏数据结构代码实现合集】【c语言学习必备】
本文记录了我为期三个月<算法与数据结构>的学习历程,仅作为记录自己学习状态的文章. 线性表 2021-9-14[数据结构/严蔚敏][顺序表][代码实现算法2.1-2.7] 2021-9-1 ...
- IT女神节(致敬中国IT界永远的女神严蔚敏-数据结构)
我们都知道程序=数据结构+算法.相信很多人都学过严蔚敏的数据结构的课程.作为一个码农,在这不管是3.7女神节,还是3.8妇女节.我觉得都有必要向这些教育界的老前辈致敬.今天我就梳理梳理,最经典的数据结 ...
- 考研961数据结构c语言版真题,严蔚敏数据结构C语言版考研真题库
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 严蔚敏<数据结构>(C语言版)配套题库[考研真题精选(部分视频讲解)+章节题库] 下载来源:http://fangcai.100xuexi.c ...
- 数据结构(严蔚敏)之二——链表的c语言实现
介绍: 1.构造一个长为n的线性表,插入元素为逆序插入 2.构造一个长为n的线性表,插入元素为顺序插入 3.销毁链表L 4.查找L的第i个元素,并用e返回 5.查找L中第一个与e满足compare关系 ...
最新文章
- 【FPGA】ROM/EPROM的设计(使用加载文件的方式初始化)
- virtio-blk简介
- Python 二维数组
- OpenGL fragmentlist片段列表的实例
- ​5G+AI时代的高效视频处理
- 实现input框的全选和清空
- c mysql二进制,MySQL运用connector C/C+读取二进制字段
- 计算机领域hpec会议,2018 IEEE High Performance extreme Computing Conference HPEC
- 日常撕逼:React和Vue到底谁更牛?
- java B2B2C 仿淘宝电子商城系统-eureka 基础
- 使用Global.asax实现ASP.Net的URL重写
- 关于删库 恢复 (慎重使用,未亲测)
- groovy 打印json_groovyJSON - Groovy教程
- 网络工程师_记录的一些真题_2017上半年上午
- 蒸汽流量计算软件_网上难得学到的知识!涡街流量计选型设计有诀窍
- YARN 作业执行流程
- 中兴承建WoStore:联通摒弃苹果“自封神话”?
- 线性查找python_C3-Linearization--线性化python
- pixiv爬虫,下载关注的所有画师的所有插画----解决谷歌人机,模拟登录,SSL错误与反反爬
- 探探自动右划,自动点击,自动加星
热门文章
- java 印章图片_Java生成印章图片
- 第二篇 线性数据结构的编程实验 第5章 应用顺序存取类线性表编程
- 国际结算业务--国际结算中的票据
- 【高数】高阶可降阶微分方程的解法?什么时候考虑把dx/dy换元(反函数高阶导数)?
- 开发,测试,生产环境中使用日志的各种姿势
- 怎么区别FLUKE DSX-8000和DSX2-8000
- 管理类书籍读后感(散落在外的那些)
- pythonweb项目打包_用python打包exe应用程序
- 关于量子计算机的中考试题,中考语文试题真题汇编现代文阅读理解训练百篇(附答案)...
- jQuery 实现显示与隐藏效果