严蔚敏《数据结构》习题(二)

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的关系,运行时间相应变长。


严蔚敏《数据结构》习题(二)相关推荐

  1. 严蔚敏数据结构习题第六章

    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 ...

  2. 严蔚敏数据结构习题第九章

    l第九章查找作业题目9.9 9.14 9.19 9.25 9.31 9.33,平台提交入口已开通,截止日期6月20日 https://www.cnblogs.com/kangjianwei101/p/ ...

  3. 严蔚敏数据结构源码及习题解析

    ⭐ 我的网站: www.mengyingjie.com ⭐ 严蔚敏数据结构源码及习题解析 习题解析未更新完整,以后更新 内容已上传到github,欢迎star和fork: https://github ...

  4. KMP算法-严蔚敏数据结构

    KMP 算法是 D.E.Knuth.J,H,Morris 和 V.R.Pratt 三位神人共同提出的,称之为 Knuth-Morria-Pratt 算法,简称 KMP 算法.该算法相对于 Brute- ...

  5. 严蔚敏数据结构C语言版——线性表的链式存储方式详细代码

    一.严蔚敏数据结构C语言版 由于书上的许多地方都是伪代码,所以下面的代码对课本上的做了一些改动,使代码能够正常运行 链表的定义即相关类型定义 typedef int ElementType; type ...

  6. 严蔚敏数据结构c++版微盘_数据结构复习知识点总结

    <数据结构>重点在线性表.树.图.查找和排序.参考书目是<数据结构>(C语言版)严蔚敏.吴伟民编著.通过对线性表.队列.栈和数组的了解,进一步理解其含义,熟悉各种例如进栈.出栈 ...

  7. 2021-10-16【严蔚敏数据结构代码实现合集】【c语言学习必备】

    本文记录了我为期三个月<算法与数据结构>的学习历程,仅作为记录自己学习状态的文章. 线性表 2021-9-14[数据结构/严蔚敏][顺序表][代码实现算法2.1-2.7] 2021-9-1 ...

  8. IT女神节(致敬中国IT界永远的女神严蔚敏-数据结构)

    我们都知道程序=数据结构+算法.相信很多人都学过严蔚敏的数据结构的课程.作为一个码农,在这不管是3.7女神节,还是3.8妇女节.我觉得都有必要向这些教育界的老前辈致敬.今天我就梳理梳理,最经典的数据结 ...

  9. 考研961数据结构c语言版真题,严蔚敏数据结构C语言版考研真题库

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 严蔚敏<数据结构>(C语言版)配套题库[考研真题精选(部分视频讲解)+章节题库] 下载来源:http://fangcai.100xuexi.c ...

  10. 数据结构(严蔚敏)之二——链表的c语言实现

    介绍: 1.构造一个长为n的线性表,插入元素为逆序插入 2.构造一个长为n的线性表,插入元素为顺序插入 3.销毁链表L 4.查找L的第i个元素,并用e返回 5.查找L中第一个与e满足compare关系 ...

最新文章

  1. 【FPGA】ROM/EPROM的设计(使用加载文件的方式初始化)
  2. virtio-blk简介
  3. Python 二维数组
  4. OpenGL fragmentlist片段列表的实例
  5. ​5G+AI时代的高效视频处理
  6. 实现input框的全选和清空
  7. c mysql二进制,MySQL运用connector C/C+读取二进制字段
  8. 计算机领域hpec会议,2018 IEEE High Performance extreme Computing Conference HPEC
  9. 日常撕逼:React和Vue到底谁更牛?
  10. java B2B2C 仿淘宝电子商城系统-eureka 基础
  11. 使用Global.asax实现ASP.Net的URL重写
  12. 关于删库 恢复 (慎重使用,未亲测)
  13. groovy 打印json_groovyJSON - Groovy教程
  14. 网络工程师_记录的一些真题_2017上半年上午
  15. 蒸汽流量计算软件_网上难得学到的知识!涡街流量计选型设计有诀窍
  16. YARN 作业执行流程
  17. 中兴承建WoStore:联通摒弃苹果“自封神话”?
  18. 线性查找python_C3-Linearization--线性化python
  19. pixiv爬虫,下载关注的所有画师的所有插画----解决谷歌人机,模拟登录,SSL错误与反反爬
  20. 探探自动右划,自动点击,自动加星

热门文章

  1. java 印章图片_Java生成印章图片
  2. 第二篇 线性数据结构的编程实验 第5章 应用顺序存取类线性表编程
  3. 国际结算业务--国际结算中的票据
  4. 【高数】高阶可降阶微分方程的解法?什么时候考虑把dx/dy换元(反函数高阶导数)?
  5. 开发,测试,生产环境中使用日志的各种姿势
  6. 怎么区别FLUKE DSX-8000和DSX2-8000
  7. 管理类书籍读后感(散落在外的那些)
  8. pythonweb项目打包_用python打包exe应用程序
  9. 关于量子计算机的中考试题,中考语文试题真题汇编现代文阅读理解训练百篇(附答案)...
  10. jQuery 实现显示与隐藏效果