1、1数 据 结 构 习 题 集 第 1章 答 案1.16 试写一算法,如果三个整数 X,Y 和 Z 的值不是依次非递增的,则通过交换,令其为非递增。要求实现下列函数:void Descend(int /* 按从大到小顺序返回 x,y 和 z 的值 */void Descend(int if(xARRSIZE 或对某个k(1kn)使 k!2kMAXINT 时,应按出错处理。注意选择你认为较好的出错处理方法。要求实现下列函数:Status Series(int ARRSIZE, int a);/* 求 i!*2i 序列的值并依次存入长度为 ARRSIZE 的数组 a; */* 若所有值均不超过 MA
2、XINT,则返回 OK,否则返回 OVERFLOW */Status Series(int ARRSIZE, int a) /* 求 i!*2i 序列的值并依次存入长度为 ARRSIZE 的数组 a; */* 若所有值均不超过 MAXINT,则返回 OK,否则返回 OVERFLOW */ int last=1; int i; if(ARRSIZEMAXINT) /*溢出判断*/ return OVERFLOW;last=ai-1; return OK; 1.20 试编写算法求一元多项式 P(x) = a0 + a1x + a2x2 + . + anxn 的值 P(x0),并确定算法中每一语句的
3、执行次数和整个算法的时间复杂度。注意选择你认为较好的输入和输出方法。要求实现下列函数:float Polynomial(int n, int a, float x0);/* 求一元多项式的值 P(x0)。 */* 数组 a 的元素 ai为 i 次项的系数,i=0,1,.,n */float Polynomial(int n, int a, float x)/* 求一元多项式的值 P(x)。 */* 数组 a 的元素 ai为 i 次项的系数,i=0,.,n */ int i,j; float s=0; /*定义一个数 s,并赋初值 0*/for(i=0;i=p;q-)*(q+1)=*q;*p=x
4、;+L.length;2.12 设 A=(a1,am)和 B=(b1,bn)均为有序顺序表, A和 B分别为 A 和 B中除去最大共同前缀后的子表(例如,A=(x,y,y,z,x,z),B=(x,y,y,z,y,x,x,z),则两者中最大的共同前缀为(x,y,y,z), 在两表中除去最大共同前缀后的子表分别为 A=(x,z)和B=(y,x,x,z)) 。若 A=B=空表,则 A=B;若 A=空表,而 B 空表,或者两者均不为空表,且 A的首元小于 B的首元,则 AB。试写一个比较 A 和 B 大小的算法。 (注意:在算法中,不要破坏原表 A 和 B,也不一定先求得 A和 B才进行比较) 。要求
5、实现下列函数:char Compare(SqList A, SqList B);/* 比较顺序表 A 和 B, */* 返回 , 若 AB */顺序表类型定义如下:typedef struct ElemType *elem;int length;int listsize; SqList;7charCompare(SqList A, SqList B)/ 比较顺序表 A 和 B, / 返回, 若 AB chara,b;intla=1,lb=1;while(la*(B.elem+lb-1)return ;elseif(*(A.elem+la-1);char a,b;int a1=1,b1=1;wh
6、ile(a1*(B.elem+b1-1) return ;else if(*(A.elem+a1-1);82.13 试写一算法在带头结点的单链表结构上实现线性表操作 Locate(L,x)。实现下列函数:LinkList Locate(LinkList L, ElemType x);/ If x in the linked list whose head node is pointed/ by L, then return pointer pointing node x,/ otherwise return NULL单链表类型定义如下:typedef struct LNode ElemType
7、 data;struct LNode *next; LNode, *LinkList;LinkList Locate(LinkList while(p)if(x=p-data)returnp;p=p-next;returnNULL;2.14 试写一算法在带头结点的单链表结构上实现线性表操作 Length(L)。实现下列函数:int Length(LinkList L);/ Return the length of the linked list9/ whose head node is pointed by L单链表类型定义如下:typedef struct LNodeElemType dat
8、a;struct LNode *next; LNode, *LinkList;intLength(LinkList L)/ Return the length of the linked list / whose head node is pointed by L inti=0;LinkList p=L;while(p-next)+i;p=p-next;returni;2.17 试写一算法,在无头结点的动态单链表上实现线性表操作 INSERT(L,i,b),并和在带头结点的动态单链表上实现相同操作的算法进行比较。实现下列函数:void Insert(LinkList 单链表类型定义如下:typ
9、edef struct LNodeElemType data;struct LNode *next; LNode, *LinkList;/思路不是很清晰,很多细节问题,调试了很长时间 /主要考虑问题:1、i 为0或负数时 2、i 在链表长度内 3、i 为链表长度+1 时 4、代码精简 10voidInsert(LinkList LinkList p=L,q=L;if(inext;if(1=i)p=(LinkList)malloc(sizeof(LNode);p-data=b;p-next=L;L=p;elseif(i1p=(LinkList)malloc(sizeof(LNode);p-dat
10、a=b;p-next=q-next;q-next=p;2.18 同2.17题要求。试写一算法,实现线性表操作 DELETE(L,i)。实现下列函数:void Delete(LinkList 单链表类型定义如下:typedef struct LNode11ElemType data;struct LNode *next; LNode, *LinkList;LinkList p=L,q;/1、求链表长度 while(p)p=p-next;+count;/2、查找第 i-1号元素 /特殊位置首位、末尾 p=L;if(1=i)L=p-next;free(p);/i=0时没问题 elseif(i1q=p
11、-next;p-next=q-next;free(q);2.20 同2.19题条件,试写一高效的算法,删除表中所有值相同的多余元素 (使得操作后的线性表中所有元素的值均不相同) 同时释放被删结点空间,并分析你的算法的时间复杂度。12实现下列函数:void Purge(LinkList 单链表类型定义如下:typedef struct LNodeElemType data;struct LNode *next; LNode, *LinkList;voidPurge(LinkList LinkList q=L-next,p=L-next;while(p)if(last=p-datafree(p);
12、p=q;elselast=p-data;q=p;p=p-next;2.21 试写一算法,实现顺序表的就地逆置,即利用原表的存储空间将线性表(a1,a2,an)逆置为(an,an-1,a1)。实现下列函数:void Inverse(SqList 顺序表类型定义如下:typedef struct 13ElemType *elem;int length;int listsize; SqList;voidInverse(SqList ElemType *p,temp;p=L.elem;for(i=0;inext; /保存首元素地址 last=L-next;/上一个指针 14cur=L-next; /当
13、前操作的指针 if(cur)while(cur)/此处没注意,写成了!cur,大意失荆州啊! cur=L-next;L-next=cur-next;cur-next=last;if(cur)last=cur;L-next=last;q-next=NULL;2.23 设线性表 A=(a1,am), B=(b1,bn),试写一个按下列规则合并 A、B 为线性表 C 的算法,即使得 C=(a1,b1,am,bm,bm+1,bn) 当 mn 时;或者 C=(a1,b1,an,bn,an+1,am) 当 mn 时。线性表 A、B 和 C 均以单链表作存储结构,且 C 表利用 A 表和 B 表中的结点空间
14、构成。注意:单链表的长度值 m 和 n 均未显式存储。实现下列函数:void Merge(LinkList ha, LinkList hb, LinkList struct LNode *next; LNode, *LinkList;voidMerge(LinkList ha, LinkList hb, LinkList cur_a=ha-next;15cur_b=hb-next;cur_c=ha;/这里要注意给 cur_c 赋值,不然地址为空 while(cur_a/Lc 的 next 指向 a; cur_c=cur_c-next;/cur_c 指向 c-next cur_a=cur_a-n
15、ext;/cur_a 指向 a-next cur_c-next=cur_b;/cur_c 的 next 指向 b cur_c=cur_c-next;/cur_c 指向 b cur_b=cur_b-next;/cur_b 指向 b-next if(cur_a)cur_c-next=cur_a;if(cur_b)cur_c-next=cur_b;hc=ha;2.24 假设有两个按元素值递增有序排列的线性表 A 和 B,均以单链表作存储结构,请编写算法将 A 表和 B 表归并成一个按元素值递减有序(即非递增有序,允许表中含有值相同的元素)排列的线性表 C, 并要求利用原表(即 A 表和 B 表)的结
16、点空间构造 C 表。实现下列函数:void Union(LinkList /* 依题意,利用 la 和 lb 原表的结点空间构造 lc 表 */单链表类型定义如下:typedef struct LNodeElemType data;struct LNode *next; LNode, *LinkList;16voidUnion(LinkList if(la-next-datanext-data)q=la-next;last=la-next;elseq=lb-next;last=lb-next;while(la-nextla-next=temp-next;temp-next=last;last=
17、temp;elsetemp=lb-next;lb-next=temp-next;temp-next=last;last=temp;/ while(la-next)temp=la-next;la-next=temp-next;temp-next=last;last=temp;while(lb-next)17temp=lb-next;lb-next=temp-next;temp-next=last;last=temp;q-next=NULL;lc=la;lc-next=temp;2.31 假设某个单向循环链表的长度大于1,且表中既无头结点也无头指针。已知 s 为指向链表中某个结点的指针,试编写算法
18、在链表中删除指针 s 所指结点的前驱结点。实现下列函数:ElemType DeleteNode(LinkList s);/* 删除指针 s 所指结点的前驱结点,并返回被删结点的元素值 */单链表类型定义如下:typedef struct LNodeElemType data;struct LNode *next; LNode, *LinkList;ElemType DeleteNode(LinkList s)/* 删除指针 s 所指结点的前驱结点,并返回被删结点的元素值 */ElemType e;LinkList p,temp=s;while(temp-next-next!=s)temp=te
19、mp-next;e=temp-next-data;p=temp-next;temp-next=s;18free(p);returne;2.32 已知有一个单向循环链表,其每个结点中含三个域:prev 、data 和 next,其中data 为数据域,next 为指向后继结点的指针域,prev 也为指针域,但它的值为空(NULL),试编写算法将此单向循环链表改为双向循环链表,即使 prev 成为指向前驱结点的指针域。实现下列函数:void PerfectBiLink(BiLinkList 双向循环链表类型定义如下:typedef struct BiNode ElemType data;int f
20、req; / 2.38题用struct BiNode *prev,*next; BiNode, *BiLinkList;voidPerfectBiLink(BiLinkList p=CL;p-next-prev=p;p=p-next;while(p!=CL)p-next-prev=p;p=p-next;2.33 已知由一个线性链表表示的线性表中含有三类字符的数据元素(如:字母字符、数字字符和其它字符) ,试编写算法将该线性链表分割为三个循环链表,其中每个循环链表表示的线性表19中均只含一类字符。实现下列函数:void Split(LinkList 单链表类型定义如下:typedef struc
21、t LNodeElemType data;struct LNode *next; LNode, *LinkList;voidSplit(LinkList p=ll-next;cur_c=lc;cur_d=ld;cur_o=lo;while(p)if(p-data=Acur_c=cur_c-next;elseif(p-data=0cur_d=cur_d-next;elsecur_o-next=p;cur_o=cur_o-next;p=p-next;20cur_c-next=lc;cur_d-next=ld;cur_o-next=lo;2.37 设以带头结点的双向循环链表表示的线性表 L=(a1,
22、a2,an)。试写一时间复杂度为 O(n)的算法,将 L 改造为 L=(a1,a3,an,a4,a2)。实现下列函数:void ReverseEven(BiLinkList 双向循环链表类型定义如下:typedef struct BiNode ElemType data;int freq; / 2.38题用struct BiNode *prev,*next; BiNode, *BiLinkList;voidReverseEven(BiLinkList intcount=0; /用 count 计结点个数 p=L-next; /p 指向第一个元素 while(p!=L-prev)/求链表长度 -
23、1 +count;p=p-next;last=p;/获得最后一个元素的地址 if(count=2)p=p-prev;while(p!=L-next)/当 p 指向的不是第一个元素时 if(0=count%2)/判断是否序号为偶数的结点 21temp=p;p=p-prev;temp-prev-next=temp-next;temp-next-prev=temp-prev;last-next=temp;temp-prev=last;last=temp;else/奇号结点则继续往前 p=p-prev;-count;last-next=L;/构建循环 L-prev=last;/构建循环 2.39 试对
24、稀疏多项式 Pn(x)采用存储量同多项式项数 m 成正比的顺序存储结构,编写求 Pn(x0)的算法(x0为给定值) ,并分析你的算法的时间复杂度。实现下列函数:float Evaluate(SqPoly pn, float x);/* pn.datai.coef 存放 ai, */* pn.datai.exp 存放 ei (i=1,2,m) */* 本算法计算并返回多项式的值。不判别溢出。 */* 入口时要求0 e1多项式的顺序存储结构 :typedef struct int coef;int exp; PolyTerm;typedef struct 22PolyTerm *data;int
25、length; SqPoly;floatEvaluate(SqPoly pn, float x)/* pn.datai.coef 存放 ai, */* pn.datai.exp 存放 ei (i=1,2,.,m) */* 本算法计算并返回多项式的值。不判别溢出。 */* 入口时要求0 e1next,last=pa-next,tail=pa-next;if(pa-next)/此处改为 cur 时遇到空表会出错,不知道为什么 if(0=last-exp)cur=cur-next;last-coef=0;while(cur!=pa)last-coef=cur-coef*(cur-exp);last-
26、exp=cur-exp-1;tail=last;last=last-next;cur=cur-next;if(cur=last-next)free(last);tail-next=pa;anyview 数 据 结 构 习 题 集 第 3章 答 案3.17 试写一个算法,识别依次读入的一个以 为结束符的字符序列是否为形如 序列1/* 若 str 是属该模式的字符序列,*/24/* 则返回 TRUE,否则返回 FALSE */Stack 是一个已实现的栈。可使用的相关类型和函数:typedef char SElemType; / 栈 Stack 的元素类型Status InitStack(Stac
27、k Status Push(Stack Status Pop(Stack Status StackEmpty(Stack s);Status GetTop(Stack s, SElemType Status match(char *str)/* 若 str 是属该模式的字符序列,*/* 则返回 TRUE,否则返回 FALSE */文档没有说明字符串是以结尾的 /也没有说栈的类型是 SqStack,用 Stack 时编译出错 SqStack s;SElemType c;Status flag=1;InitStack(s);char*cur=str;while(+cur;/入栈 +cur;if(!
28、GetTop(s,c)/判断栈空 while(*cur!= )Pop(s,c);if(c!=*cur)flag=0;break;+cur;25/依次出栈匹配 if(GetTop(s,c)flag=0;/再次判断是否非空 returnflag;3.18 试写一个判别表达式中开、闭括号是否配对出现的算法。实现下列函数:Status MatchCheck(SqList exp);/* 顺序表 exp 表示表达式; */* 若 exp 中的括号配对,则返回 TRUE,否则返回 FALSE */* 注:本函数不使用栈 */顺序表类型定义如下:typedef struct ElemType *elem;i
29、nt length;int listsize; SqList; / 顺序表Status MatchCheck(SqList exp)/* 顺序表 exp 表示表达式; */* 若 exp 中的括号配对,则返回 TRUE,否则返回 FALSE */* 注:本函数不使用栈 */*/ 此题 top 指针和 cur 指针要很仔细地运用,还有判错条件也要小心 ElemType *cur,*top,*base;base=exp.elem;/模拟栈底 top=cur=base+1;/模拟栈顶(top)和当前元素(cur) if()=*cur)returnFALSE;/判断第一个字符是否为右括号 if(0=exp.length)26returnTRUE;/判断是否为空顺序表 while(curm|j0n)exit(OVERFLOW);30x=i0;y=j0;color=gxy;doif(x0break;/东临 case2:+x;break;/南 case3:-y;break;/西 case4:-x;break;/北 Push(S,di);