《数据结构》耿国华版算法习题.docx
- 文档编号:8571258
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:47
- 大小:81.51KB
《数据结构》耿国华版算法习题.docx
《《数据结构》耿国华版算法习题.docx》由会员分享,可在线阅读,更多相关《《数据结构》耿国华版算法习题.docx(47页珍藏版)》请在冰豆网上搜索。
《数据结构》耿国华版算法习题
《数据结构》耿国华版算法习题
第一部分 线性表
1./*有序表上插入新元素*/
typedefintdatatype;
#definemaxsize1000
typedefstruct
{datatypelist[maxsize];
intsize;/**/
}sequenlist;/*顺序表类型定义*/
intins2_4_1(sequenlist*L,datatypex)/*从后向前比较*/
{inti;
if(L->size>=maxsize)
{
printf("溢出");
return0;
}
else
{
for(i=L->size-1;i>=0;i--)
if(x
L->data[i+1]=L->data[i];
else
break;
/*以上for循环也可以改为:
for(i=L->size-1;i>=0&&x
L->data[i+1]=L->data[i];
*/
L->data[i+1]=x;
L->last++;
return1;
}
}
ins2_4_2(sequenlist*L,datatypex)/*从前向后比较*/
{inti,j;
if(L->size>=maxsize)
{
printf("溢出");
return0;
}
else
{
for(i=0;i<=L->last;i++)
if(x<=L->data[i])
break;
/*以上for循环也可以改为:
for(i=0;i<=L->last&&x>L->data[i];i++);
*/
for(j=L->last;j>=I;j--)
L->data[j+1]=L->data[j];
L->data[i]=x;
L->last++;
return1;
}
}
2:
删除顺序表中,从第i个元素开始的k个元素。
intDELETE(seqlist*L,inti,intk)/*seqlist顺序表类型*/
{intj;
if(i>L->last)/*起始位置超出表长,无法删除*/
{printf("error");
return0;
}
else
{if(i+k-2>L->last)/*从起始位置开始不足K个元素,则将起始位置到表尾全部删除*/
{L->last=i-2;/*此时不进行元素的移动,覆盖*/
}
else
{for(j=i+k-1;j<=L->last;j++)
/*i+k-1下标的元素覆盖i-1,i+k下标元素覆盖i,以此类推,直到L->last*/
L->data[j-k]=L->data[j];
L->last=L->last-k;
}
return1;
}
}
3
/*删除值递增的单链表中,所有大于mink且小于maxk的元素*/
ch2_6(linklistH,intmink,intmaxk)/*H为带头结点的单链表*/
{linklistp,q;
if(mink<=maxk)
{p=H;
while(p->next!
=NULL)
{if(p->next->data>=mink&&p->next->data {q=p->next; p->next=q->next; free(q); } else p=p->next; } } else {p=H; while(p->next! =NULL) {if(p->next->data>=mink||p->next->data {q=p->next; p->next=q->next; free(q); } else p=p->next; } } } 4 ch2_7a(seqlist*l)/*顺序存储*/ {intI,temp; for(i=0;i<=l->last/2;i++) {temp=l->data[i]; l->data[i]=l->data[l->last-i]; l->data[l->last-i]=temp; } } /*带头结点单链表逆序*/ typedefintdatatype; typedefstructnode {datatypedata; structnode*next; }*linklist; nixu(linklistl) {linklistp,q; q=l->next; l->next=NULL; while(q! =NULL) {p=q; q=q->next; p->next=l->next; l->next=p; } } 5: 非递减有序的表A,B,合并成非递增有序的表C。 (存储结构,单链表) 方法: 依次从A或B表中得到最小值,使用前插法生成表C。 typedefstructnode {intdata; structnode*next; }NODE,*LinkList; LinkListunion(LinkListA,LinkListB) {LinkListC; LinkListpa,pb,min; C=malloc(sizeof(NODE)); C->next=NULL; pa=A->next; pb=B->next; while(pa! =NULL&&pb! =NULL) {if(pa->data {min=pa; pa=pa->next; } else {min=pb; pb=pb->next; } min->next=C->next; C->next=min; } while(pa! =NULL) {min=pa; pa=pa->next; min->next=C->next; C->next=min; } while(pb! =NULL) {min=pb; pb=pb->next; min->next=C->next; C->next=min; } returnC; } 6/*删除长度大于的1的循环单链表中s结点的先驱结点,无头结点无头指针*/ ch2_9(linklists) {linklistp,q; p=s; while(p->next->next! =s) p=p->next; q=p->next; p->next=s; free(q); } 7/*将一单链表中的结点按类型分为三个循环链表*/ chaifen(linklistl,linklista,linklistb,linklistc) {linklistp,ra,rb,rc; l=l->next; ra=a; rb=b; rc=c; while(l! =NULL) {if(l->data>'0'&&l->data<'9') {ra->next=l; ra=l; } else if(l->data>'a'&&l->data<'z'||l->data>'A'&&l->data<'Z') {rb->next=l; rb=l; } else {rc->next=l; rc=l; } l=l->next; } ra->next=a; rb->next=b; rc->next=c; } 8将一个表示稀疏多项式的循环链表分解成各奇偶次项的链表*/ typedefstructpolynode {intcoef; intexp; structpolynode*next; }*polylist; ch2_12(polylista,polylistb,polylistc) {polylistpa,ra,pb,pc; b=malloc(sizeof(structpolynode)); pb=b; c=malloc(sizeof(structpolynode)); pc=c; ra=a->next; while(ra! =NULL) {pa=ra; ra=ra->next; if(pa->coef%2==0) {pb->next=pa; pb=pa; } else {pc->next=pa; pc=pa; } pb->next=NULL; pc->next=NULL; free(a); } 9/*二进制的加1运算*/ ch2_13(linklista) {inttemp=1; linklistp,q=NULL; while(temp==1) { if(q! =a->next) {p=a; while(p->next! =q) p=p->next; } else {p=malloc(sizeof(linklist)); p->data=0; p->next=a->next; a->next=p; } if(p->data==0) {p->data=1; temp=0; } else {p->data=0; q=p; } } } 第二部分 栈和队列 1. 写一个算法,判断依次读入的一个以@为结束符的字母序列,是否为形如'序列1&序列2'模式的字符序列。 其中序列1和序列2都不含字符'&',且序列2是序列1的逆序列。 思路: 将字符串中&符以前的符号入栈保存,跳过&符,出栈并和新遇到的字符比较,不相等,结论为不对称,相等,继续比较,直到遇到@符。 若当前符号为@且栈空,为对称,否则都为不对称。 typedefstruct { charelem[MAX]; inttop; }seqstack; intch3_5(char*str)/*判断字符串str是否回文*/ { seqstackS;/*栈,用于存储@符以前的字符*/ while(*str! ='@'&&*str! ='&')/*遇到符号@,或&以前的符号入栈*/ { push(S,*str); str++; } if(*str=='@')/*先遇到@,不是回文*/ return0; str++;/*跳过&符号*/ while(*str! ='@')/*对&符以后,@以前的符号做回文判断*/ {Gettop(S,&ch); if(*str==ch) {pop(S,&ch); str++; } else break; } if(*str=='@'&&IsEmpty(S)==1)/*当前字符取完且栈空,是回文*/ return1; else return0; } 2. 例: 源表达式为: (a+b*c)-d/e 逆波兰式表达式为: abc*+de/- 思路: 使用栈来保存操作符,且调整操作符的运算顺序,使用队列来保存结果字符串,一旦遇到字母字符就入队,遇到操作符字符需要利用栈,和之前的操作符比较,决定入栈继续保存或是取出放在结果中。 ch3_6(char*expr,char*result)/*expr为源表达式字符串,result为求得的逆波兰式表达式字符串*/ { seqstackS; seqqueueQ; charop; InitStack(S);/*初始化栈*/ InitQueue(Q);/*初始化队列*/ push(S,'#');/*将符号'#'入栈*/ while(*expr! ='\0') { if(*expr>='a'&&*expr<='z') {enqueue(Q,*expr);/*字母字符入队*/ expr++; } else { gettop(S,&ch); switch(comp(*expr,ch))/*比较当前操作符与栈顶字符的优先级*/ { '>': push(S,*expr); expr++; break; '=': pop(S,&ch); expr++; break; '<': pop(S,&ch); enqueue(Q,ch); } } } while(! IsEmptyStack(S))/*原字符串遇到'\0'时,在栈中的操作符依次出栈,入队*/ { pop(S,&ch); enqueue(Q,ch); } while(! IsEmptyQueue(Q))/*将队列中的内容按顺序出队,写入字符串result*/ {dequeue(Q,&ch); *result=ch; result++; } *result='\0'; } 3.假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾元素结点(不设头指针),试编写相应的队列初始化,入队列,出队列的算法。 注意: 这是链式存储结构。 typedefstructnode {Elemtypedata; structnode*next; }Node,*LinkList; InitQueue(LinkListQ) {Q=malloc(sizeof(Node)); Q->next=Q; } EnQueue(LinkListQ,Elemtypex) { Node*p; p=malloc(sizeof(Node)); p->data=x; p->next=Q->next; Q->next=p; Q=p; } DeQueue(LinkListQ,Elemtype*x) { Node*p; p=Q->next->next; Q->next->next=p->next; *x=p->data; free(p); } 4.要求循环队列不损失一个空间全部都能得到利用,设置一个标志域tag,以tag为0或1来区分头尾指针相同时的队列状态的空与满,请编写与此结构相应的入队与出队算法。 typedefstruct { datatypedata[MAX]; intf; intr; inttag;//标志域 }seqqueue; 解法1、(设f指向队首,r指向队尾,则用tag区别f=r时,是空队还是只有一个元素的非空队,即tag=0表示空队,tag=1时表示所有非空情况,当(Q->r+1)%MAX==Q->f时表示队满;入队时,队尾指针后移,但入第一个元素时,队首指针也指向这唯一元素;出队时,队首指针后移,但当队列出到空时,两个指针都不移动) enterqueue(seqqueue*Q,datatypex) { if((Q->r+1)%MAX==Q->f) {队满,退出} else {Q->r=(Q->r+1)%MAX; Q->data[Q->r]=x; if(tag==0) {Q->f=Q->r; //新元素也是队首 Q->tag=1;//空队变为非空队 } } } deletequeue(seqqueue*Q,datatype*x) { if(Q->tag==0) {队空,退出} else {*x=Q->data[Q->f]; if(Q->f==Q->r ) //只有一个元素的队列,因含在else分支中,条件Q->tag==1的判断可省略 { Q->f=(Q->f+1)%MAX; Q->r=Q->f; Q->tag=0; } else { Q->f=(Q->f+1)%MAX; } } } 解法2、(设f指向队首,r指向队尾,则用tag区别(r+1)%MAX=f时,是队满还是队空,即tag=0表示所有非满的队列,tag=1时表示队满情况,当(Q->r+1)%MAX==Q->f且tag=1时表示队满;当(Q->r+1)%MAX==Q->f且tag=1时表示队空;入队时,队尾指针后移;出队时,队首指针后移; 应当注意: 此种情况下,应设初始化时,Q->f=1;Q->r=0;Q->tag=0 ,以与队列删除到空时的状态一致) enterqueue(seqqueue*Q,datatypex) { if((Q->tag==1) {队满,退出} else {Q->r=(Q->r+1)%MAX; Q->data[Q->r]=x; if((Q->r+1)%MAX==Q->f) Q->tag==1; } } deletequeue(seqqueue*Q,datatype*x) { if(Q->tag==0&&(Q->r+1)%MAX==Q->f) {队空,退出} else {*x=Q->data[Q->f]; Q->f=(Q->f+1)%MAX; if(Q->tag==1) //若原队为满状态 { Q->tag=0;//出队元素后,队为非满状态 } } } 解法3: (设f指向队首,r指向队尾的下一个位置,与课本设置方法一致,则用tag区别f=r时,是队满还是队空,即tag=0表示队空,tag=1时表示队满,当Q->r==Q->f且tag=0时表示队空;当Q->r ==Q->f且tag=1时表示队满;入队时,队尾指针后移;出队时,队首指针后移) enterqueue(seqqueue*Q,datatypex) { if((Q->tag==1 &&Q->f==Q->r) { 队满,退出 } else {Q->data[Q->r]=x;//新元素入队尾指针当前位置 Q->r=(Q->r+1)%MAX; //队尾指针后移 if(Q->f==Q->r)//因入队至队满 { Q->tag=1; } } } deletequeue(seqqueue*Q,datatype*x) { if(Q->tag==0) {队空,退出} else {*x=Q->data[Q->f]; Q->f=(Q->f+1) % MAX ; if(Q->f==Q->r) //因出队而队空 { Q->tag=0; } } } 第三部分: 串 顺序串的定义: typedefstruct { charch[maxsize]; intlen;/*表示长度,最后一个元素的下标为len-1*/ }string; (1)将顺序串r中的所有值为ch1的字符换成ch2. stringreplace(string*r,charch1,charch2) { for(i=0;i if(r->ch[i]==ch1) r->ch[i]=ch2; returnr; } 要点: 1.顺序串的内容被修改,形参一定是顺序串的地址,所以r为指针类型,且在函数体内的引用一定是"r->" 2.注意本题参数有三个: 顺序串,字符1,字符2.都是已知量,而且顺序串将被修改.又是结果.所以可以将顺序串做为返回值(也可以不用返回值,一样可以得到结果,但有返回值时,这个函数就可以放在表达式中被嵌套调用了). (2).串r中所有字符按照相反的次序仍存放在r中. 解法1: stringchanged(string*r) { for(i=0;i<(r->len)/2;i++) { t=r->ch[i]; r->ch[i]=r->ch[r->len-i-1]; r->ch[r->len-i-1]=t; } returnr; } 要点: 1.函数只有一个参数: r,为已知量,而且也是结果. 解法2.. 这样解也可以: 用两个下标,分别指向第一个元素,最后一个元素,两者交换后,两个下标再重新取值.一个递增,一个递减. stringchanged(string*r) { for(i=0,j=r->len-1;i<(r->len)/2;i++,j--) { t=r->ch[i]; r->ch[i]=r->ch[j]; r->ch[j]=t; } returnr; } 解法3..如下的解法也可以,但是既花时间,又付出空间 stringchanged(string*r) { strings;/*注意此时,s不能设为指针类型*/ for(i=r->len-1,j=0;i>=0;i--,j++) s.ch[j]=r->ch[i]; for(i=0;i r->ch[i]=s.ch[i]; returnr; } (3) 从顺序串r中删除其值等于ch的所有字符 解法一: delete(string*r,charch) { strings; for(i=0,j=0;i if(r->ch[i]! =ch) s.ch[j++]=r->ch[i]; for(i=0;i r->ch[i]=s.ch[i];/*把s的内容写回到r中*/ r->len=j;/*修改r的表长*/ } 解法二: delete(string*
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 数据结构耿国华版 算法习题 国华 算法 习题