严蔚敏习题集解答三
数据结构题集答案(C语言版)(严蔚敏,吴伟民著)-推荐下载

Get(C,k,&e) 操作结果:用 e 返回复数 C 的第 k 元的值
Put(&C,k,e) 操作结果:改变复数 C 的第 k 元的值为 e
IsAscending(C) 操作结果:如果复数 C 的两个元素按升序排列,则返回 1,否
则返回 0 IsDescending(C) 操作结果:如果复数 C 的两个元素按降序排列,则返回 1,否
解: ADT Complex{
数据对象:D={r,i|r,i 为实数} 数据关系:R={<r,i>} 基本操作:
InitComplex(&C,re,imDestroyCmoplex(&C) 操作结果:销毁复数 C
对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料电试力卷保相护互装作置用调与试相技互术关,系电通,力1根保过据护管生高线产中0不工资仅艺料可高试以中卷解资配决料置吊试技顶卷术层要是配求指置,机不对组规电在范气进高设行中备继资进电料行保试空护卷载高问与中题带资2负料2,荷试而下卷且高总可中体保资配障料置各试时类卷,管调需路控要习试在题验最到;大位对限。设度在备内管进来路行确敷调保设整机过使组程其高1在中正资,常料要工试加况卷强下安看与全22过,22度并22工且22作尽22下可护都能1关可地于以缩管正小路常故高工障中作高资;中料对资试于料卷继试连电卷接保破管护坏口进范处行围理整,高核或中对者资定对料值某试,些卷审异弯核常扁与高度校中固对资定图料盒纸试位,卷置编工.写况保复进护杂行层设自防备动腐与处跨装理接置,地高尤线中其弯资要曲料避半试免径卷错标调误高试高等方中,案资要,料求编试技5写、卷术重电保交要气护底设设装。备备置管4高调、动线中试电作敷资高气,设料中课并技3试资件且、术卷料中拒管试试调绝路包验卷试动敷含方技作设线案术,技槽以来术、及避管系免架统不等启必多动要项方高方案中式;资,对料为整试解套卷决启突高动然中过停语程机文中。电高因气中此课资,件料电中试力管卷高壁电中薄气资、设料接备试口进卷不行保严调护等试装问工置题作调,并试合且技理进术利行,用过要管关求线运电敷行力设高保技中护术资装。料置线试做缆卷到敷技准设术确原指灵则导活:。。在对对分于于线调差盒试动处过保,程护当中装不高置同中高电资中压料资回试料路卷试交技卷叉术调时问试,题技应,术采作是用为指金调发属试电隔人机板员一进,变行需压隔要器开在组处事在理前发;掌生同握内一图部线纸故槽资障内料时,、,强设需电备要回制进路造行须厂外同家部时出电切具源断高高习中中题资资电料料源试试,卷卷线试切缆验除敷报从设告而完与采毕相用,关高要技中进术资行资料检料试查,卷和并主检且要测了保处解护理现装。场置设。备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。
最新严蔚敏 数据结构课后习题及答案解析资料

第一章绪论一、选择题1.组成数据的基本单位是()(A)数据项(B)数据类型(C)数据元素(D)数据变量2.数据结构是研究数据的()以及它们之间的相互关系。
(A)理想结构,物理结构(B)理想结构,抽象结构(C)物理结构,逻辑结构(D)抽象结构,逻辑结构3.在数据结构中,从逻辑上可以把数据结构分成()(A)动态结构和静态结构(B)紧凑结构和非紧凑结构(C)线性结构和非线性结构(D)内部结构和外部结构4.数据结构是一门研究非数值计算的程序设计问题中计算机的(①)以及它们之间的(②)和运算等的学科。
①(A)数据元素(B)计算方法(C)逻辑存储(D)数据映像②(A)结构(B)关系(C)运算(D)算法5.算法分析的目的是()。
(A)找出数据结构的合理性(B)研究算法中的输入和输出的关系(C)分析算法的效率以求改进(D)分析算法的易懂性和文档性6.计算机算法指的是(①),它必须具备输入、输出和(②)等5个特性。
①(A)计算方法(B)排序方法(C)解决问题的有限运算序列(D)调度方法②(A)可执行性、可移植性和可扩充性(B)可行性、确定性和有穷性(C)确定性、有穷性和稳定性(D)易读性、稳定性和安全性二、判断题1.数据的机内表示称为数据的存储结构。
()2.算法就是程序。
()3.数据元素是数据的最小单位。
()4.算法的五个特性为:有穷性、输入、输出、完成性和确定性。
()5.算法的时间复杂度取决于问题的规模和待处理数据的初态。
()三、填空题1.数据逻辑结构包括________、________、_________ 和_________四种类型,其中树形结构和图形结构合称为_____。
2.在线性结构中,第一个结点____前驱结点,其余每个结点有且只有______个前驱结点;最后一个结点______后续结点,其余每个结点有且只有_______个后续结点。
3.在树形结构中,树根结点没有_______结点,其余每个结点有且只有_______个前驱结点;叶子结点没有________结点,其余每个结点的后续结点可以_________。
数据结构(C语言版)第2版习题答案—严蔚敏

四类基本逻辑结构关系图
4.存储结构由哪两种基本的存储方法实现?
答案:
( 1)顺序存储结构
顺序存储结构是借助元素在存储器中的相对位置来表示数据元素之间的逻辑关系,通常
借助程序设计语言的数组类型来描述。
( 2)链式存储结构
顺序存储结构要求所有的元素依次存放在一片连续的存储空间中,而链式存储结构,无
2
第 2 章 线性表
1.选择题
( 1)顺 序表中 第一个 元 素的存储 地址 是 100 ,每 个元素的 长度 为 2,则 第 5 个 元 素 的
地 址 是(
)。
A . 110 答案: B
B . 108
C. 100
D . 120
解释:顺序表中的数据连续存储,所以第
5 个元素的地址为: 100+2*4=108 。
( 2)在 n 个结点的顺序表中,算法的时间复杂度是
O(1) 的操作是( )。
A .访问第 i 个结点( 1≤ i≤ n)和求第 i 个结点的直接前驱( 2≤ i≤ n)
B .在第 i 个结点后插入一个新结点( 1≤ i ≤ n)
C.删除第 i 个结点( 1≤ i≤ n)
D .将 n 个结点从小到大排序 答案: A
动 的元素个数为(
)。
A.8
B . 63.5
C. 63
D. 7
答案: B
解释:平均要移动的元素个数为: n/2。
( 4)链接存储的存储结构所占存储空间(
)。
A .分两部分,一部分存放结点值,另一部分存放表示结点间关系的指针 B .只有一部分,存放结点值
C.只有一部分,存储表示结点间关系的指针
D .分两部分,一部分存放结点值,另一部分存放结点所占单元数
严蔚敏版数据结构课后习题答案-完整版

第1章绪论1.1 简述下列术语:数据,数据元素、数据对象、数据结构、存储结构、数据类型和抽象数据类型。
解:数据是对客观事物的符号表示。
在计算机科学中是指所有能输入到计算机中并被计算机程序处理的符号的总称。
数据元素是数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理。
数据对象是性质相同的数据元素的集合,是数据的一个子集。
数据结构是相互之间存在一种或多种特定关系的数据元素的集合。
存储结构是数据结构在计算机中的表示。
数据类型是一个值的集合和定义在这个值集上的一组操作的总称。
抽象数据类型是指一个数学模型以及定义在该模型上的一组操作。
是对一般数据类型的扩展。
1.2 试描述数据结构和抽象数据类型的概念与程序设计语言中数据类型概念的区别。
解:抽象数据类型包含一般数据类型的概念,但含义比一般数据类型更广、更抽象。
一般数据类型由具体语言系统内部定义,直接提供给编程者定义用户数据,因此称它们为预定义数据类型。
抽象数据类型通常由编程者定义,包括定义它所使用的数据和在这些数据上所进行的操作。
在定义抽象数据类型中的数据部分和操作部分时,要求只定义到数据的逻辑结构和操作说明,不考虑数据的存储结构和操作的具体实现,这样抽象层次更高,更能为其他用户提供良好的使用接口。
1.3 设有数据结构(D,R),其中{}4,3,2,1d d d d D =,{}r R =,()()(){}4,3,3,2,2,1d d d d d d r =试按图论中图的画法惯例画出其逻辑结构图。
解:1.4 试仿照三元组的抽象数据类型分别写出抽象数据类型复数和有理数的定义(有理数是其分子、分母均为自然数且分母不为零的分数)。
解:ADT Complex{数据对象:D={r,i|r,i 为实数}数据关系:R={<r,i>}基本操作: InitComplex(&C,re,im)操作结果:构造一个复数C ,其实部和虚部分别为re和imDestroyCmoplex(&C)操作结果:销毁复数CGet(C,k,&e)操作结果:用e返回复数C的第k元的值Put(&C,k,e)操作结果:改变复数C的第k元的值为eIsAscending(C)操作结果:如果复数C的两个元素按升序排列,则返回1,否则返回0IsDescending(C)操作结果:如果复数C的两个元素按降序排列,则返回1,否则返回0Max(C,&e)操作结果:用e返回复数C的两个元素中值较大的一个Min(C,&e)操作结果:用e返回复数C的两个元素中值较小的一个}ADT ComplexADT RationalNumber{数据对象:D={s,m|s,m为自然数,且m不为0}数据关系:R={<s,m>}基本操作:InitRationalNumber(&R,s,m)操作结果:构造一个有理数R,其分子和分母分别为s和mDestroyRationalNumber(&R)操作结果:销毁有理数RGet(R,k,&e)操作结果:用e返回有理数R的第k元的值Put(&R,k,e)操作结果:改变有理数R的第k元的值为eIsAscending(R)操作结果:若有理数R的两个元素按升序排列,则返回1,否则返回0IsDescending(R)操作结果:若有理数R的两个元素按降序排列,则返回1,否则返回0Max(R,&e)操作结果:用e返回有理数R的两个元素中值较大的一个Min(R,&e)操作结果:用e返回有理数R的两个元素中值较小的一个}ADT RationalNumber1.5 试画出与下列程序段等价的框图。
数据结构习题集答案_C语言版(严蔚敏 吴伟民)

n(n + 1) 2
( 5 )1 + ( 1 + 2 ) + ( 1 + 2 + 3 ) + . . . + ( 1 + 2 + 3 + . . . + n ) =
∑
i =1
n
i(i + 1) 2
=
1 n 1 n 2 1 n 2 1 n ( 1 ) ( ) i i + = i + i = i ∑ ∑ ∑i + 2 ∑ 2 i =1 2 i =1 2 i =1 i =1
( 6 )i = 1 ;j = 0 ; w h i l e ( i + j < = n ){ @ i f ( i > j )j + + ; e l s ei + + ; } ( 7 )x = n ;y = 0 ; @ y + + ; } ( 8 )x = 9 1 ;y = 1 0 0 ; w h i l e ( y > 0 ){ @ i f ( x > 1 0 0 ){x=1 0 ;y ;} e l s ex + + ; } 解:( 1 )n 1 ( 2 )n 1 ( 3 )n 1 ( 4 )n + ( n 1 ) + ( n 2 ) + . . . + 1 = / /n 是不小于 1 的常数 w h i l e ( x > = ( y + 1 ) * ( y + 1 ) ){
n) n−2
1 . 1 1已知有实现同一功能的两个算法,其时间复杂度分别为 O
(2 ) 和 O(n ) ,假设现实计算机可连续
n 10
大数据结构习题集问题详解(c版)(清华大学严蔚敏)

1.16void print_descending(int x,int y,int z)//按从大到小顺序输出三个数{scanf("%d,%d,%d",&x,&y,&z);if(x<y) x<->y; //<->为表示交换的双目运算符,以下同if(y<z) y<->z;if(x<y) x<->y; //冒泡排序printf("%d %d %d",x,y,z);}//print_descending1.17Status fib(int k,int m,int &f)//求k阶斐波那契序列的第m项的值f{int tempd;if(k<2||m<0) return ERROR;if(m<k-1) f=0;else if (m==k-1) f=1;else{for(i=0;i<=k-2;i++) temp=0;temp[k-1]=1; //初始化for(i=k;i<=m;i++) //求出序列第k至第m个元素的值{sum=0;for(j=i-k;j<i;j++) sum+=temp[j];temp=sum;}f=temp[m];}return OK;}//fib分析:通过保存已经计算出来的结果,此方法的时间复杂度仅为O(m^2).如果采用递归编程(大多数人都会首先想到递归方法),则时间复杂度将高达O(k^m).1.18typedef struct{char *sport;enum{male,female} gender;char schoolname; //校名为'A','B','C','D'或'E'char *result;int score;} resulttype;typedef struct{int malescore;int femalescore;int totalscore;} scoretype;void summary(resulttype result[ ])//求各校的男女总分和团体总分,假设结果已经储存在result[ ]数组中{scoretype score;i=0;while(result.sport!=NULL){switch(result.schoolname){case 'A':score[ 0 ].totalscore+=result.score;if(result.gender==0) score[ 0 ].malescore+=result.score;else score[ 0 ].femalescore+=result.score;break;case 'B':score.totalscore+=result.score;if(result.gender==0) score.malescore+=result.score;else score.femalescore+=result.score;break;……?……?……}i++;}for(i=0;i<5;i++){printf("School %d:\n",i);printf("Total score of male:%d\n",score.malescore);printf("Total score of female:%d\n",score.femalescore);printf("Total score of all:%d\n\n",score.totalscore);}}//summary1.19Status algo119(int a[ARRSIZE])//求i!*2^i序列的值且不超过maxint{last=1;for(i=1;i<=ARRSIZE;i++){a[i-1]=last*2*i;if((a[i-1]/last)!=(2*i)) reurn OVERFLOW;last=a[i-1];return OK;}}//algo119分析:当某一项的结果超过了maxint时,它除以前面一项的商会发生异常.1.20void polyvalue(){float ad;float *p=a;printf("Input number of terms:");scanf("%d",&n);printf("Input the %d coefficients from a0 to a%d:\n",n,n);for(i=0;i<=n;i++) scanf("%f",p++);printf("Input value of x:");scanf("%f",&x);p=a;xp=1;sum=0; //xp用于存放x的i次方for(i=0;i<=n;i++){sum+=xp*(*p++);xp*=x;}printf("Value is:%f",sum);}//polyvalue2.10Status DeleteK(SqList &a,int i,int k)//删除线性表a中第i个元素起的k个元素{if(i<1||k<0||i+k-1>a.length) return INFEASIBLE;for(count=1;i+count-1<=a.length-k;count++) //注意循环结束的条件a.elem[i+count-1]=a.elem[i+count+k-1];a.length-=k;return OK;}//DeleteK2.11Status Insert_SqList(SqList &va,int x)//把x插入递增有序表va中{if(va.length+1>va.listsize) return ERROR;va.length++;for(i=va.length-1;va.elem>x&&i>=0;i--)va.elem[i+1]=va.elem;va.elem[i+1]=x;return OK;}//Insert_SqList2.12int ListComp(SqList A,SqList B)//比较字符表A和B,并用返回值表示结果,值为正,表示A>B;值为负,表示A<B;值为零,表示A=B{for(i=1;A.elem||B.elem;i++)if(A.elem!=B.elem) return A.elem-B.elem;return 0;}//ListComp2.13LNode* Locate(LinkList L,int x)//链表上的元素查找,返回指针{for(p=l->next;p&&p->data!=x;p=p->next);return p;}//Locate2.14int Length(LinkList L)//求链表的长度{for(k=0,p=L;p->next;p=p->next,k++);return k;}//Length2.15void ListConcat(LinkList ha,LinkList hb,LinkList &hc)//把链表hb接在ha后面形成链表hc{hc=ha;p=ha;while(p->next) p=p->next;p->next=hb;}//ListConcat2.16见书后答案.2.17Status Insert(LinkList &L,int i,int b)//在无头结点链表L的第i个元素之前插入元素b{p=L;q=(LinkList*)malloc(sizeof(LNode));q.data=b;if(i==1){q.next=p;L=q; //插入在链表头部}else{while(--i>1) p=p->next;q->next=p->next;p->next=q; //插入在第i个元素的位置}}//Insert2.18Status Delete(LinkList &L,int i)//在无头结点链表L中删除第i个元素{if(i==1) L=L->next; //删除第一个元素else{p=L;while(--i>1) p=p->next;p->next=p->next->next; //删除第i个元素}}//Delete2.19Status Delete_Between(Linklist &L,int mink,int maxk)//删除元素递增排列的链表L 中值大于mink且小于maxk的所有元素{p=L;while(p->next->data<=mink) p=p->next; //p是最后一个不大于mink的元素if(p->next) //如果还有比mink更大的元素{q=p->next;while(q->data<maxk) q=q->next; //q是第一个不小于maxk的元素p->next=q;}}//Delete_Between2.20Status Delete_Equal(Linklist &L)//删除元素递增排列的链表L中所有值相同的元素{p=L->next;q=p->next; //p,q指向相邻两元素while(p->next){if(p->data!=q->data){p=p->next;q=p->next; //当相邻两元素不相等时,p,q都向后推一步}else{while(q->data==p->data){free(q);q=q->next;}p->next=q;p=q;q=p->next; //当相邻元素相等时删除多余元素}//else}//while}//Delete_Equal2.21void reverse(SqList &A)//顺序表的就地逆置{for(i=1,j=A.length;i<j;i++,j--)A.elem<->A.elem[j];}//reverse2.22void LinkList_reverse(Linklist &L)//链表的就地逆置;为简化算法,假设表长大于2 {p=L->next;q=p->next;s=q->next;p->next=NULL;while(s->next){q->next=p;p=q;q=s;s=s->next; //把L的元素逐个插入新表表头}q->next=p;s->next=q;L->next=s;}//LinkList_reverse分析:本算法的思想是,逐个地把L的当前元素q插入新的链表头部,p为新表表头.2.23void merge1(LinkList &A,LinkList &B,LinkList &C)//把链表A和B合并为C,A和B的元素间隔排列,且使用原存储空间{p=A->next;q=B->next;C=A;while(p&&q){s=p->next;p->next=q; //将B的元素插入if(s){t=q->next;q->next=s; //如A非空,将A的元素插入}p=s;q=t;}//while}//merge12.24void reverse_merge(LinkList &A,LinkList &B,LinkList &C)//把元素递增排列的链表A 和B合并为C,且C中元素递减排列,使用原空间{pa=A->next;pb=B->next;pre=NULL; //pa和pb分别指向A,B的当前元素while(pa||pb){if(pa->data<pb->data||!pb){pc=pa;q=pa->next;pa->next=pre;pa=q; //将A的元素插入新表}else{pc=pb;q=pb->next;pb->next=pre;pb=q; //将B的元素插入新表}pre=pc;}C=A;A->next=pc; //构造新表头}//reverse_merge分析:本算法的思想是,按从小到大的顺序依次把A和B的元素插入新表的头部pc处,最后处理A或B的剩余元素.2.25void SqList_Intersect(SqList A,SqList B,SqList &C)//求元素递增排列的线性表A和B 的元素的交集并存入C中{i=1;j=1;k=0;while(A.elem&&B.elem[j]){if(A.elem<B.elem[j]) i++;if(A.elem>B.elem[j]) j++;if(A.elem==B.elem[j]){C.elem[++k]=A.elem; //当发现了一个在A,B中都存在的元素,i++;j++; //就添加到C中}}//while}//SqList_Intersect2.26void LinkList_Intersect(LinkList A,LinkList B,LinkList &C)//在链表结构上重做上题{p=A->next;q=B->next;pc=(LNode*)malloc(sizeof(LNode));while(p&&q){if(p->data<q->data) p=p->next;else if(p->data>q->data) q=q->next;else{s=(LNode*)malloc(sizeof(LNode));s->data=p->data;pc->next=s;pc=s;p=p->next;q=q->next;}}//whileC=pc;}//LinkList_Intersect2.27void SqList_Intersect_True(SqList &A,SqList B)//求元素递增排列的线性表A和B的元素的交集并存回A中{i=1;j=1;k=0;while(A.elem&&B.elem[j]){if(A.elem<B.elem[j]) i++;else if(A.elem>B.elem[j]) j++;else if(A.elem!=A.elem[k]){A.elem[++k]=A.elem; //当发现了一个在A,B中都存在的元素i++;j++; //且C中没有,就添加到C中}}//whilewhile(A.elem[k]) A.elem[k++]=0;}//SqList_Intersect_True2.28void LinkList_Intersect_True(LinkList &A,LinkList B)//在链表结构上重做上题{p=A->next;q=B->next;pc=A;while(p&&q){if(p->data<q->data) p=p->next;else if(p->data>q->data) q=q->next;else if(p->data!=pc->data){pc=pc->next;pc->data=p->data;p=p->next;q=q->next;}}//while}//LinkList_Intersect_True2.29void SqList_Intersect_Delete(SqList &A,SqList B,SqList C){i=0;j=0;k=0;m=0; //i指示A中元素原来的位置,m为移动后的位置while(i<A.length&&j<B.length&& k<C.length){if(B.elem[j]<C.elem[k]) j++;else if(B.elem[j]>C.elem[k]) k++;elsesame=B.elem[j]; //找到了相同元素samewhile(B.elem[j]==same) j++;while(C.elem[k]==same) k++; //j,k后移到新的元素while(i<A.length&&A.elem<same)A.elem[m++]=A.elem[i++]; //需保留的元素移动到新位置while(i<A.length&&A.elem==same) i++; //跳过相同的元素}}//whilewhile(i<A.length)A.elem[m++]=A.elem[i++]; //A的剩余元素重新存储。
数据结构第2版习题答案解析-严蔚敏
数据结构(C语言版)(第2版)课后习题答案李冬梅目录第1章绪论............................................. 错误!未定义书签。
第2章线性表........................................... 错误!未定义书签。
第3章栈和队列......................................... 错误!未定义书签。
第4章串、数组和广义表................................. 错误!未定义书签。
第5章树和二叉树....................................... 错误!未定义书签。
第6章图................................................ 错误!未定义书签。
第7章查找............................................. 错误!未定义书签。
第8章排序............................................. 错误!未定义书签。
第1章绪论1.简述下列概念:数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、抽象数据类型。
答案:数据:是客观事物的符号表示,指所有能输入到计算机中并被计算机程序处理的符号的总称。
如数学计算中用到的整数和实数,文本编辑所用到的字符串,多媒体程序处理的图形、图像、声音、动画等通过特殊编码定义后的数据。
数据元素:是数据的基本单位,在计算机中通常作为一个整体进行考虑和处理。
在有些情况下,数据元素也称为元素、结点、记录等。
数据元素用于完整地描述一个对象,如一个学生记录,树中棋盘的一个格局(状态)、图中的一个顶点等。
数据项:是组成数据元素的、有独立含义的、不可分割的最小单位。
例如,学生基本信息表中的学号、姓名、性别等都是数据项。
严蔚敏版数据结构课后习题答案-完整版
第1章 绪论之巴公井开创作简述下列术语:数据,数据元素、数据对象、数据结构、存储结构、数据类型和笼统数据类型.解:数据是对客观事物的符号暗示.在计算机科学中是指所有能输入到计算机中并被计算机法式处置的符号的总称.数据元素是数据的基本单元,在计算机法式中通常作为一个整体进行考虑和处置.数据对象是性质相同的数据元素的集合,是数据的一个子集. 数据结构是相互之间存在一种或多种特定关系的数据元素的集合.存储结构是数据结构在计算机中的暗示.数据类型是一个值的集合和界说在这个值集上的一组把持的总称.笼统数据类型是指一个数学模型以及界说在该模型上的一组把持.是对一般数据类型的扩展.试描述数据结构和笼统数据类型的概念与法式设计语言中数据类型概念的区别.解:笼统数据类型包括一般数据类型的概念,但含义比一般数据类型更广、更笼统.一般数据类型由具体语言系统内部界说,直接提供给编程者界说用户数据,因此称它们为预界说数据类型.笼统数据类型通常由编程者界说,包括界说它所使用的数据和在这些数据上所进行的把持.在界说笼统数据类型中的数据部份和把持部份时,要求只界说到数据的逻辑结构和把持说明,不考虑数据的存储结构和把持的具体实现,这样笼统条理更高,更能为其他用户提供良好的使用接口.1.3 设有数据结构(D,R),其中{}4,3,2,1d d d d D =,{}r R =,()()(){}4,3,3,2,2,1d d d d d d r =试按图论中图的画法惯例画出其逻辑结构图.解:1.4 试仿照三元组的笼统数据类型分别写出笼统数据类型复数和有理数的界说(有理数是其分子、分母均为自然数且分母不为零的分数).解:ADT Complex{数据对象:D={r,i|r,i为实数}数据关系:R={<r,i>}基本把持:InitComplex(&C,re,im)把持结果:构造一个复数C,其实部和虚部份别为re和imDestroyCmoplex(&C)把持结果:销毁复数CGet(C,k,&e)把持结果:用e返回复数C的第k元的值Put(&C,k,e)把持结果:改变复数C的第k元的值为eIsAscending(C)把持结果:如果复数C的两个元素按升序排列,则返回1,否则返回0IsDescending(C)把持结果:如果复数C的两个元素按降序排列,则返回1,否则返回0Max(C,&e)把持结果:用e返回复数C的两个元素中值较年夜的一个Min(C,&e)把持结果:用e返回复数C的两个元素中值较小的一个}ADT ComplexADT RationalNumber{数据对象:D={s,m|s,m为自然数,且m不为0}数据关系:R={<s,m>}基本把持:InitRationalNumber(&R,s,m)把持结果:构造一个有理数R,其分子和分母分别为s和mDestroyRationalNumber(&R)把持结果:销毁有理数RGet(R,k,&e)把持结果:用e返回有理数R的第k元的值Put(&R,k,e)把持结果:改变有理数R的第k元的值为eIsAscending(R)把持结果:若有理数R的两个元素按升序排列,则返回1,否则返回0IsDescending(R)把持结果:若有理数R的两个元素按降序排列,则返回1,否则返回0Max(R,&e)把持结果:用e返回有理数R的两个元素中值较年夜的一个Min(R,&e)把持结果:用e返回有理数R的两个元素中值较小的一个}ADT RationalNumber1.5 试画出与下列法式段等价的框图.(1) product=1; i=1;while(i<=n){product *= i;i++;}(2) i=0;do {i++;} while((i!=n) && (a[i]!=x));(3) switch {case x<y: z=y-x; break;case x=y: z=abs(x*y); break;default: z=(x-y)/abs(x)*abs(y);}1.6 在法式设计中,经常使用下列三种分歧的犯错处置方式:(1) 用exit语句终止执行并陈说毛病;(2) 以函数的返回值区别正确返回或毛病返回;(3) 设置一个整型变量的函数参数以区别正确返回或某种毛病返回.试讨论这三种方法各自的优缺点.解:(1)exit经常使用于异常毛病处置,它可以强行中断法式的执行,返回把持系统.(2)以函数的返回值判断正确与否经常使用于子法式的测试,便于实现法式的局部控制.(3)用整型函数进行毛病处置的优点是可以给犯毛病类型,便于迅速确定毛病.1.7 在法式设计中,可采纳下列三种方法实现输出和输入:(1) 通过scanf和printf语句;(2) 通过函数的参数显式传递;(3) 通过全局变量隐式传递.试讨论这三种方法的优缺点.解:(1)用scanf和printf直接进行输入输出的好处是形象、直观,但缺点是需要对其进行格式控制,较为烦琐,如果呈现毛病,则会引起整个系统的解体.(2)通过函数的参数传递进行输入输出,便于实现信息的隐蔽,减少犯错的可能.(3)通过全局变量的隐式传递进行输入输出最为方便,只需修改变量的值即可,但过多的全局变量使法式的维护较为困难.1.8 设n为正整数.试确定下列各法式段中前置以记号@的语句的频度:(1) i=1; k=0;while(i<=n-1){@ k += 10*i;i++;}(2) i=1; k=0;do {@ k += 10*i;i++;} while(i<=n-1);(3) i=1; k=0;while (i<=n-1) { i++;@ k += 10*i;}(4) k=0;for(i=1; i<=n; i++) {for(j=i; j<=n; j++)@ k++;}(5) for(i=1; i<=n; i++) {for(j=1; j<=i; j++) {for(k=1; k<=j; k++)@ x += delta;}(6) i=1; j=0;while(i+j<=n) { @ if(i>j) j++;else i++;}(7) x=n; y=0; // n是不小于1的常数while(x>=(y+1)*(y+1)) {@ y++;}(8) x=91; y=100;while(y>0) {@ if(x>100) { x -= 10; y--; }else x++;}解:(1) n-1(2) n-1(3) n-1(4) n+(n-1)+(n-2)+...+1=2)1(+ n n(5) 1+(1+2)+(1+2+3)+...+(1+2+3+...+n)=∑=+ nii i12)1(=∑∑∑∑====+=+=+ninininiiiiii i1121212121)(21)1(21=)32)(1(121)1(41)12)(1(121++=++++nnnnnnnn(6) n(7)⎣⎦n向下取整(8) 11001.9 假设n为2的乘幂,而且n>2,试求下列算法的时间复杂度及变量count的值(以n的函数形式暗示).int Time(int n) { count = 0;x=2; while(x<n/2) { x *= 2;count++; }return count; }解:)(log 2n o count=2log 2-n1.11 已知有实现同一功能的两个算法,其时间复杂度分别为()nO 2和()10n O ,假设现实计算机可连续运算的时间为710秒(100多天),又每秒可执行基本把持(根据这些把持来估算算法时间复杂度)510次.试问在此条件下,这两个算法可解问题的规模(即n 值的范围)各为几多?哪个算法更适宜?请说明理由.解:12102=n n=40 121010=n n=16则对同样的循环次数n,在这个规模下,第二种算法所花费的价格要年夜很多.故在这个规模下,第一种算法更适宜. 1.12 设有以下三个函数:()10002124++=n n n f ,()3450015n n n g +=,()n n n n h log 5005.3+= 请判断以下断言正确与否:(1) f(n)是O(g(n)) (2) h(n)是O(f(n)) (3) g(n)是O(h(n)) (4) h(n)是O(n)(5) h(n)是O(nlogn)解:(1)对 (2)错 (3)错 (4)对 (5)错1.13 试设定若干n 值,比力两函数2n 和n n 2log 50的增长趋势,并确定n 在什么范围内,函数2n 的值年夜于n n 2log 50的值.解:2n 的增长趋势快.但在n 较小的时候,n n 2log 50的值较年夜. 当n>438时,n n n 22log 50>1.14 判断下列各对函数()n f 和()n g ,那时∞→n ,哪个函数增长更快?(1) ()()310!ln 102nn n n f ++=,()724++=n n n g(2)()()()25!ln +=n n f ,()5.213n n g =(3)()141.2++=n n n f ,()()()n n n g +=2!ln (4) ()()()2223n n n f +=,()()52n n n g n +=解:(1)g(n)快 (2)g(n)快 (3)f(n)快 (4) f(n)快5 试用数学归纳法证明: (1) ()()6/12112++=∑=n n n ini ()0≥n(2) ()()1/11--=+=∑x xx n ni i()0,1≥≠n x(3) 12211-=∑=-n ni i ()1≥n(4) ()2112n i n i =-∑=()1≥n1.16 试写一算法,自年夜至小依次输出顺序读入的三个整数X,Y 和Z 的值解:int max3(int x,int y,int z) {if(x>y)if(x>z) return x; else return z; elseif(y>z) return y; else return z; }1.17 已知k 阶斐波那契序列的界说为0=f ,01=f ,…,02=-k f ,11=-k f ;kn n n n f f f f ---+++= 21, ,1,+=k k n试编写求k 阶斐波那契序列的第m 项值的函数算法,k 和m 均以值调用的形式在函数参数表中呈现.解:k>0为阶数,n 为数列的第n 项 int Fibonacci(int k,int n) {if(k<1) exit(OVERFLOW);int *p,x;p=new int[k+1];if(!p) exit(OVERFLOW);int i,j;for(i=0;i<k+1;i++){if(i<k-1) p[i]=0;else p[i]=1;}for(i=k+1;i<n+1;i++){x=p[0];for(j=0;j<k;j++) p[j]=p[j+1];p[k]=2*p[k-1]-x;}return p[k];}1.18 假设有A,B,C,D,E五个高等院校进行田径对立赛,各院校的,并输出.解:typedef enum{A,B,C,D,E} SchoolName;typedef enum{Female,Male} SexType;typedef struct{char event[3]; //项目SexType sex;SchoolName school;int score;} Component;typedef struct{int MaleSum;//男团总分int FemaleSum;//女团总分int TotalSum;//团体总分} Sum;Sum SumScore(SchoolName sn,Component a[],int n){Sum temp;temp.MaleSum=0; temp.FemaleSum=0; temp.TotalSum=0; int i;for(i=0;i<n;i++){ if(a[i].school==sn){if(a[i].sex==Male) temp.MaleSum+=a[i].score;if(a[i].sex==Female) temp.FemaleSum+=a[i].score; } }temp.TotalSum=temp.MaleSum+temp.FemaleSum; return temp; }1.19 试编写算法,计算ii 2!*的值并存入数组a[0..arrsize-1]的第i-1个分量中(i=1,2,…,n).假设计算机中允许的整数最年夜值为maxint,则当n>arrsize 或对某个()n k k ≤≤1,使int max 2!>•kk 时,应按犯错处置.注意选择你认为较好的犯错处置方法.解:#include<iostream.h> #include<stdlib.h> #define MAXINT 65535 #define ArrSize 100 int fun(int i); int main() {int i,k;int a[ArrSize]; cout<<"Enter k:"; cin>>k;if(k>ArrSize-1) exit(0); for(i=0;i<=k;i++){ if(i==0) a[i]=1; else{if(2*i*a[i-1]>MAXINT) exit(0); else a[i]=2*i*a[i-1]; }}for(i=0;i<=k;i++){if(a[i]>MAXINT) exit(0); else cout<<a[i]<<" "; }return 0; }1.20 试编写算法求一元多项式的值()∑==ni ii n x a x P 0的值()0x P n ,并确定算法中每一语句的执行次数和整个算法的时间复杂度.注意选择你认为较好的输入和输出方法.本题的输入为()n i a i ,,1,0 =,0x 和n ,输出为()0x P n .解:#include<iostream.h> #include<stdlib.h> #define N 10double polynomail(int a[],int i,double x,int n); int main() {double x; int n,i; int a[N];cout<<"输入变量的值x:"; cin>>x;cout<<"输入多项式的阶次n:"; cin>>n;if(n>N-1) exit(0);cout<<"输入多项式的系数a[0]--a[n]:"; for(i=0;i<=n;i++) cin>>a[i]; cout<<"The polynomail value is"<<polynomail(a,n,x,n)<<endl; return 0; }double polynomail(int a[],int i,double x,int n) {if(i>0) return a[n-i]+polynomail(a,i-1,x,n)*x;else return a[n];}本算法的时间复杂度为o(n).第2章线性表2.1 描述以下三个概念的区别:头指针,头结点,首元结点(第一个元素结点).解:头指针是指向链表中第一个结点的指针.首元结点是指链表中存储第一个数据元素的结点.头结点是在首元结点之前附设的一个结点,该结点不存储数据元素,其指针域指向首元结点,其作用主要是为了方便对链表的把持.它可以对空表、非空表以及首元结点的把持进行统一处置.2.2 填空题.解:(1) 在顺序表中拔出或删除一个元素,需要平均移动表中一半元素,具体移动的元素个数与元素在表中的位置有关.(2) 顺序表中逻辑上相邻的元素的物理位置肯定紧邻.单链表中逻辑上相邻的元素的物理位置纷歧定紧邻.(3) 在单链表中,除首元结点外,任一结点的存储位置由其前驱结点的链域的值指示.(4) 在单链表中设置头结点的作用是拔出和删除首元结点时不用进行特殊处置.2.3 在什么情况下用顺序表比链表好?解:当线性表的数据元素在物理位置上是连续存储的时候,用顺序表比用链表好,其特点是可以进行随机存取.2.4 对以下单链表分别执行下列各法式段,并画出结果示意图.解:2.5 画出执行下列各行语句后各指针及链表的示意图.L=(LinkList)malloc(sizeof(LNode));P=L;for(i=1;i<=4;i++){P->next=(LinkList)malloc(sizeof(LNode));P=P->next;P->data=i*2-1;}P->next=NULL;for(i=4;i>=1;i--) Ins_LinkList(L,i+1,i*2);for(i=1;i<=3;i++) Del_LinkList(L,i);解:2.6 已知L是无表头结点的单链表,且P结点既不是首元结点,也不是尾元结点,试从下列提供的谜底中选择合适的语句序列.a. 在P结点后拔出S结点的语句序列是__________________.b. 在P结点前拔出S结点的语句序列是__________________.c. 在表首拔出S结点的语句序列是__________________.d. 在表尾拔出S结点的语句序列是__________________.(1) P->next=S;(2) P->next=P->next->next;(3) P->next=S->next;(4) S->next=P->next;(5) S->next=L;(6) S->next=NULL;(7) Q=P;(8) while(P->next!=Q) P=P->next;(9) while(P->next!=NULL) P=P->next;(10) P=Q;(11) P=L;(12) L=S;(13) L=P;解:a. (4) (1)b. (7) (11) (8) (4) (1)c. (5) (12)d. (9) (1) (6)2.7 已知L是带表头结点的非空单链表,且P结点既不是首元结点,也不是尾元结点,试从下列提供的谜底中选择合适的语句序列.a. 删除P结点的直接后继结点的语句序列是____________________.b. 删除P结点的直接前驱结点的语句序列是____________________.c. 删除P结点的语句序列是____________________.d. 删除首元结点的语句序列是____________________.e. 删除尾元结点的语句序列是____________________.(1) P=P->next;(2) P->next=P;(3) P->next=P->next->next;(4) P=P->next->next;(5) while(P!=NULL) P=P->next;(6) while(Q->next!=NULL) { P=Q; Q=Q->next; }(7) while(P->next!=Q) P=P->next;(8) while(P->next->next!=Q) P=P->next;(9) while(P->next->next!=NULL) P=P->next;(10) Q=P;(11) Q=P->next;(12) P=L;(13) L=L->next;(14) free(Q);解:a. (11) (3) (14)b. (10) (12) (8) (3) (14)c. (10) (12) (7) (3) (14)d. (12) (11) (3) (14)e. (9) (11) (3) (14)2.8 已知P结点是某双向链表的中间结点,试从下列提供的谜底中选择合适的语句序列.a. 在P结点后拔出S结点的语句序列是_______________________.b. 在P结点前拔出S结点的语句序列是_______________________.c. 删除P结点的直接后继结点的语句序列是_______________________.d. 删除P结点的直接前驱结点的语句序列是_______________________.e. 删除P结点的语句序列是_______________________.(1) P->next=P->next->next;(2) P->priou=P->priou->priou;(3) P->next=S;(4) P->priou=S;(5) S->next=P;(6) S->priou=P;(7) S->next=P->next;(8) S->priou=P->priou;(9) P->priou->next=P->next;(10) P->priou->next=P;(11) P->next->priou=P;(12) P->next->priou=S;(13) P->priou->next=S;(14) P->next->priou=P->priou;(15) Q=P->next;(16) Q=P->priou;(17) free(P);(18) free(Q);解:a. (7) (3) (6) (12)b. (8) (4) (5) (13)c. (15) (1) (11) (18)d. (16) (2) (10) (18)e. (14) (9) (17)2.9 简述以下算法的功能.(1) Status A(LinkedList L) { //L是无表头结点的单链表if(L && L->next) {Q=L;L=L->next;P=L;while(P->next) P=P->next;P->next=Q;Q->next=NULL;}return OK;}(2) void BB(LNode *s, LNode *q) {p=s;while(p->next!=q) p=p->next;p->next =s;}void AA(LNode *pa, LNode *pb) {//pa和pb分别指向单循环链表中的两个结点BB(pa,pb);BB(pb,pa);}解:(1) 如果L的长度不小于2,将L的首元结点酿成尾元结点.(2) 将单循环链表拆成两个单循环链表.2.10 指出以下算法中的毛病和低效之处,并将它改写为一个既正确又高效的算法.Status DeleteK(SqList &a,int i,int k){//本过程从顺序存储结构的线性表a中删除第i个元素起的k 个元素if(i<1||k<0||i+k>a.length) return INFEASIBLE;//参数分歧法else {for(count=1;count<k;count++){//删除第一个元素for(j=a.length;j>=i+1;j--) a.elem[j-i]=a.elem[j];a.length--;}return OK;}解:Status DeleteK(SqList &a,int i,int k){//从顺序存储结构的线性表a中删除第i个元素起的k个元素//注意i的编号从0开始int j;if(i<0||i>a.length-1||k<0||k>a.length-i) return INFEASIBLE;for(j=0;j<=k;j++)a.elem[j+i]=a.elem[j+i+k];a.length=a.length-k;return OK;}2.11 设顺序表va中的数据元素递增有序.试写一算法,将x拔出到顺序表的适当位置上,以坚持该表的有序性.解:Status InsertOrderList(SqList &va,ElemType x){//在非递加的顺序表va中拔出元素x并使其仍成为顺序表的算法int i;if(va.length==va.listsize)return(OVERFLOW);for(i=va.length;i>0,x<va.elem[i-1];i--)va.elem[i]=va.elem[i-1];va.elem[i]=x;va.length++;return OK;}2.12 设()m a a A ,,1 =和()n b b B ,,1 =均为顺序表,A '和B '分别为A 和B 中除去最年夜共同前缀后的子表.若='='B A 空表,则B A =;若A '=空表,而≠'B 空表,或者两者均不为空表,且A '的首元小于B '的首元,则B A <;否则B A >.试写一个比力A ,B 年夜小的算法.解:Status CompareOrderList(SqList &A,SqList &B){int i,k,j;k=A.length>B.length?A.length:B.length;for(i=0;i<k;i++){if(A.elem[i]>B.elem[i]) j=1;if(A.elem[i]<B.elem[i]) j=-1;}if(A.length>k) j=1;if(B.length>k) j=-1;if(A.length==B.length) j=0;return j;}2.13 试写一算法在带头结点的单链表结构上实现线性表把持Locate(L,x);解:int LocateElem_L(LinkList &L,ElemType x){int i=0;LinkList p=L;while(p&&p->data!=x){p=p->next;i++;}if(!p) return 0;else return i;}2.14 试写一算法在带头结点的单链表结构上实现线性表把持Length(L).解://返回单链表的长度int ListLength_L(LinkList &L) {int i=0;。
严蔚敏数据结构题集(C语言版)史上最全答案(一题可有多解)
第1章绪论1.1解:数据是对客观事物的符号表示。
在计算机科学中是指所有能输入到计算机中并被计算机程序处理的符号的总称。
数据元素是数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理。
数据对象是性质相同的数据元素的集合,是数据的一个子集。
数据结构是相互之间存在一种或多种特定关系的数据元素的集合。
存储结构是数据结构在计算机中的表示。
数据类型是一个值的集合和定义在这个值集上的一组操作的总称。
抽象数据类型是指一个数学模型以及定义在该模型上的一组操作。
是对一般数据类型的扩展。
1.2 试描述数据结构和抽象数据类型的概念与程序设计语言中数据类型概念的区别。
解:抽象数据类型包含一般数据类型的概念,但含义比一般数据类型更广、更抽象。
一般数据类型由具体语言系统内部定义,直接提供给编程者定义用户数据,因此称它们为预定义数据类型。
抽象数据类型通常由编程者定义,包括定义它所使用的数据和在这些数据上所进行的操作。
在定义抽象数据类型中的数据部分和操作部分时,要求只定义到数据的逻辑结构和操作说明,不考虑数据的存储结构和操作的具体实现,这样抽象层次更高,更能为其他用户提供良好的使用接口。
1.3 解:1.4 解:ADT Complex{数据对象:D={r,i|r,i为实数}数据关系:R={<r,i>}基本操作:InitComplex(&C,re,im)操作结果:构造一个复数C,其实部和虚部分别为re和imDestroyCmoplex(&C)操作结果:销毁复数CGet(C,k,&e)操作结果:用e返回复数C的第k元的值Put(&C,k,e)操作结果:改变复数C的第k元的值为eIsAscending(C)操作结果:如果复数C的两个元素按升序排列,则返回1,否则返回0IsDescending(C)操作结果:如果复数C的两个元素按降序排列,则返回1,否则返回0Max(C,&e)操作结果:用e返回复数C的两个元素中值较大的一个Min(C,&e)操作结果:用e返回复数C的两个元素中值较小的一个}ADT ComplexADT RationalNumber{数据对象:D={s,m|s,m为自然数,且m不为0}数据关系:R={<s,m>}基本操作:InitRationalNumber(&R,s,m)操作结果:构造一个有理数R,其分子和分母分别为s和mDestroyRationalNumber(&R)操作结果:销毁有理数RGet(R,k,&e)操作结果:用e返回有理数R的第k元的值Put(&R,k,e)操作结果:改变有理数R的第k元的值为eIsAscending(R)操作结果:若有理数R的两个元素按升序排列,则返回1,否则返回0IsDescending(R)操作结果:若有理数R的两个元素按降序排列,则返回1,否则返回0Max(R,&e)操作结果:用e 返回有理数R 的两个元素中值较大的一个Min(R,&e)操作结果:用e 返回有理数R 的两个元素中值较小的一个}ADT RationalNumber1.5 试画出与下列程序段等价的框图。
数据结构习题集(C语言版严蔚敏)第一二三章
第1章 绪论1.1 简述下列术语:数据,数据元素、数据对象、数据结构、存储结构、数据类型和抽象数据类型。
1.2 试描述数据结构和抽象数据类型的概念与程序设计语言中数据类型概念的区别。
1.3 设有数据结构(D,R),其中{}4,3,2,1d d d d D =,{}r R =,()()(){}4,3,3,2,2,1d d d d d d r =试按图论中图的画法惯例画出其逻辑结构图。
1.4 试仿照三元组的抽象数据类型分别写出抽象数据类型复数和有理数的定义(有理数是其分子、分母均为自然数且分母不为零的分数)。
1.5 试画出与下列程序段等价的框图。
(1) product=1; i=1; while(i<=n){ product *= i; i++; } (2) i=0; do { i++;} while((i!=n) && (a[i]!=x)); (3) switch {case x<y: z=y-x; break; case x=y: z=abs(x*y); break; default: z=(x-y)/abs(x)*abs(y); }1.6 在程序设计中,常用下列三种不同的出错处理方式:(1) 用exit 语句终止执行并报告错误; (2) 以函数的返回值区别正确返回或错误返回;(3) 设置一个整型变量的函数参数以区别正确返回或某种错误返回。
试讨论这三种方法各自的优缺点。
1.7 在程序设计中,可采用下列三种方法实现输出和输入:(1) 通过scanf 和printf 语句; (2) 通过函数的参数显式传递; (3) 通过全局变量隐式传递。
试讨论这三种方法的优缺点。
1.8 设n 为正整数。
试确定下列各程序段中前置以记号@的语句的频度:(1) i=1; k=0;while(i<=n-1){@ k += 10*i;i++;}(2) i=1; k=0;do {@ k += 10*i;i++;} while(i<=n-1);(3) i=1; k=0;while (i<=n-1) {i++;@ k += 10*i;}(4) k=0;for(i=1; i<=n; i++) {for(j=i; j<=n; j++)@ k++;}(5) for(i=1; i<=n; i++) {for(j=1; j<=i; j++) {for(k=1; k<=j; k++)@ x += delta;}(6) i=1; j=0;while(i+j<=n) {@ if(i>j) j++;else i++;}(7) x=n; y=0; // n是不小于1的常数while(x>=(y+1)*(y+1)) {@ y++;}(8) x=91; y=100;while(y>0) {@ if(x>100) { x -= 10; y--; }else x++;}1.9 假设n为2的乘幂,并且n>2,试求下列算法的时间复杂度及变量count的值(以n的函数形式表示)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#define STACK_INIT_SIZE 100; #define STACKINCREMENT 10; typedef struct { SElemType *base; SElemType *top; int stacksize; }SqStack; *************************************************************************************************************************** Status InitStack(SqStack &S) {// S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType)); if(!S.base) return ERROR; S.top=S.base; S.stacksize=STACK_INIT_SIZE; return; } *************************************************************************************************************************** Status GetTop(SqStack S, SElemType e) {// if(S.top==S.base) return ERROR; e=*(S.top-1); return e; } *************************************************************************************************************************** Status Push(SqStack &S, SElemType e) {// if(S.top-S.base>=S.stacksize) { S.base=(SElemType *)realloc(S.base,(STACK_INIT_SIZE+STACKINCREMENT)*sizeof(SElemType)); if(S.base) exit(OVERFLOW); S.top=S.base+S.stacksize; S.stacksize+=STACKINCREMENT; } *S.top++=e; return OK; }//Push *************************************************************************************************************************** Status Pop(SqStack &S, SElemType &e) {// if(S.top==S.base) return ERROR; e=*--S.top; return OK; }//Pop *************************************************************************************************************************** Void Transform(char suffix[], char exp[]) {//求表达式的后缀式。 InitStack(S); Push(S,'#'); p=exp; ch=*p; while(!StackEmpty(S)) { if(!IN(ch,OP)) Pass(Suffix,ch); else { switch(ch) { case '(': Push(S,ch); break; case ')': { Pop(S,c); while(c!='(') {Pass(Suffix,c); Pop(S,c); break; } default: { while(!GetTop(S,c)&&(Precede(c,ch))) { Pass(Suffix,c); Pop(S,c); } if(ch!='#') Push(S,ch); break; } }//switch }//else if(ch!='#') {P++; ch=*p;} }while } *************************************************************************************************************************** OperandType EvaluateExpression() {//算术表达式求值的算符优先算法。设OPTR和OPND分别运算符栈和操作数栈,OP为运算符集。 InitStack(OPTR) InitStack(OPND); Push(S,'#'); c=getchar(); while(c!='#'||GetTop(S)!='#') { if(!IN(c,OP) { Push(OPND,c); c=getchar();} else switch(Precede(Gettop(OPTR),c)) { case '<': Push(OPTR,c), c=getchar(); break; case '=': Pop(OPTR,c), c=getchar(); break; case '>': Pop(OPTR,theta); Pop(OPND,b); Pop(OPND,a); Push(OPND,Operate(a,theta,b)); } }//while] return Gettop(OPND); }//EvaluateExpression *************************************************************************************************************************** P23/3.5¥¥¥¥ 假设以S和X分别表示入栈和出栈的操作,则初态和终态均为栈空的入栈和出栈的操作序列可以表示为仅由S和X组成的序列。称可以操作的序列为合法序列。试给出区分给定序列为合法序列或非法序列的一般准则,并证明:两个不同的合法(栈操作)序列(对同一输入序列)不可能得到相同的输出元素(注意:在此指的是元素实体,而不是值)序列。 1.原则如下: 1)从操作序列中第一个字符起的任何一个子序列中,'S'的个数不少于'X'的个数; 2)整个序列中,'S'的个数和'X'的个数相同。 2.用反证法。 证明:假设两个不同的合法序列:T1=U1,U2,...,Un; T2=V1,V2,...,Vn; Ui,Vi属于{S,X} i=1,2,...,n 可以得到相同的输出元素序列。 不失一般性,假设第一个不同的操作为:Uk='S'!=Vk='X' 既Uj=Vj,j=1,2,3,...,k-1 则此时,已输出的元素序列相同,栈的状态也相同,且栈中至少存在一个元素(不然的话,操作序列V中第k个操作为出栈,不符合第一个规则,V就为非法的操作序列)。现假设栈顶元素为x,正待输入的元素为y, 则根据栈的后进先出的原则,由T1得到的输出序列中,x领先于y,而由T2得到的输出序列中,y领先于x。由此证得,两个不同的合法操作序列不可能得到相同的输出元素序列。 *************************************************************************************************************************** P23/3.10 试将下列递归过程改为非递归过程。 void test(int &sum) { int x; scanf(x); if(!x) sum=0; else { test(sum);} sum+=x; printf(sum); } --------------------------------------------------------------------------------------------------------------------------- 设输入为:5,3,1,0 则输出为0,1,4,9 void ditui(int sum) { InitStack(S) scanf(x); while(x) { Push(S,x); scanf(x); } sum=0; printf(sum); while(!StackEmpty(S)) { sum+=Pop(S); printf(sum); } } *************************************************************************************************************************** P24/3.14 若以1234作为双端队列的输入序列,试分别求出满足下列条件的输出队列: (1)能由输入受限的双端队列得到,但不能由输出受限的双端队列得到输出序列; (2)能由输出受限的双端队列得到,但不能由输入受限的双端队列得到输出序列; (3)既不能由输入受限的双端队列得到,也不能由输出受限的双端队列得到输出序列; 解答如下: 由题设条件若以1234作为输入序列,在不受任何限制的条件下最多只有4!=24种输出序列,对于输入受限的双端队列或输出受限的双端队列这两种数据结构在输入输出操作上受到的限制比栈少,先求出以1234作为栈的输入序列的输出序列,然后放宽条件分别求出在相同的输入序列的情况下输入受限的双端队列和输出受限的双端队列的输出序列。 总共由如下24种可能输出序列: 1234 2134 3124 4123 1243 2143 3142 4132 1324 2314 3214 4213 1342 2341 3241 4231 1423 2413 3412 4312 1432 2431 3421 4321 从上面输出序列种可得出如下14种作为栈的输出序列: 1234,1243,1324,1342,1432,2134,2143,2314,2341,2431,3214,3241,3421,4321. 显然,这14种输出序列上述良种双端队列都能得到,于是从剩下的10种可能输出序列种找剩下的可能的输出序列。 输入受限的双端队列的输出序列: 1423,2413,3124,3142,4123,4132,4312(4213,4231不可能出现)。 输出受限的双端队列的输出序列: