实用数据结构基础(第三版)课后答案

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
int correct (char a[ ])
{
stack s ;
InitStack (s);//调用初始化栈函数
for (i=0; i <strlen(a);i++)
if (a[i]= =’(’)
Push (s,’(’);
else
if (a[i]= =’)’)
{
if StackEmpty (s)//调用判栈空函数
struct node
{ elemtype data;
node*next;
};
void lkinsert (node *head, elemtype x)
{ node*s,*p;
s=new node;
s->data=x;
p=head->next;
while (p!=NULL) && ( p->data!=a )
解://用一个循环数组Queue[0,n-1]表示该循环队列,头指针为front,计数器count用来记录队列中结点的个数。
//队列为空:count==0
//队列为满:count=MAXLEN
//队尾第一个元素位置==(front+count)%MAXLEN
//队首第一个元素位置==(front+1)%MAXLEN
}QueueNode;
InQueue(QueueNode *rear,int x)// 向队列插入元素为x的函数
{ QueueNode *rear;
QueueNode *head,*s;
s=new QueueNode;
s->data=x;
if(rear==NULL)// 循环队列为空,则建立一个结点的循环队列
if(count==0)
printf("队列下溢出\n");
else
{ temp=Queue[front];
front=(front+1)%n;
count--;
return temp;
}
}
(2)用一个循环数组Q[0..MAXLEN-1]表示队列时,该队列只有一个头指针front,不设尾指针,而改置一个记数器count用以记录队列中结点的个数。试编写一个能实现:初始化队列、判队空、读队头元素、入队操作和出队操作的算法。
③读队头元素
void ReadFront(int queue[],x)
{
if (count==0)
}linkstack;
void Conversion(int n)//栈的应用:十——十六进制转换
{linkstack s;
int x;
s.top=NULL;//置栈空
do
{ x=n%16;//取余数
n=n/16;//取新的商
stacknode *p=new stacknode;//申请新结点
p->next=s.top;//修改栈顶指针
}
(2)已知一个单向链表,编写一个函数从单链表中删除自第i个结点起的k个结点。
解:
void Del(node *head,int i,int k)
{
node *p,*q;
int j;
if(i==1)
for(j=1;j<=k;j++) //删除前k个元素
{
p=head; // p指向要删除的结点
head=head->next;
解:A B + C * E F G H / + / - D -
58/(5+2)-6
解:8 5 2 + / 6 -
六.算法设计题
(1)设用一维数组stack[n]表示一个堆栈,若堆栈中每个元素需占用M个数组单元(M>1)。
①试写出其入栈操作的算法。
②试写出其出栈操作的算法。
解://用一整型变量top表示栈顶指针,top为0时表示栈为空。栈中元素从S [1]开始存放元素。
解://本题是遍历单链表的每个结点,每遇到一个结点,结点个数加1,结点个数存储在变量n中。实现本题功能的函数如下:
int counter(head)
node *head;
{ node *p;
int n=0;
p=head;
while(p!=NULL)
{ if(p->data==x)
n++;
p=p->next;
{
if (top= =0)
printf (“堆栈为空栈!”);
else
{Βιβλιοθήκη Baidu
if (top= =1)
{
x=S[top];
top––;
}
else
{
x=S[top];
top=top–M;
}
}
}
(2)设计一个算法,要求判别一个算术表达式中的圆括号配对是否正确。
解://设表达式在字符数组a[ ]中,使用一堆栈S来帮助判断。
s.top=p;
s.top->data=x;//余数入栈
}
while(n);
printf("\n\t\t转换后的十六进制数值为:";
while (s.top)//出栈处理
{if(s.top->data<10);
printf("%d",s.top->data);
else
switch(s.top->data)
____p=p->next;
if (p==NULL)
cout<< "不存在结点a! ";
else {_____s->next=p->next______;
___ p->next=s __________;
}
}
六.算法设计题
(1)写一个对单循环链表进行遍历(打印每个结点的值)的算法,已知链表中任意结点的地址为P。
//①入栈算法:
void push(charx)
{
if ((top+M)>MAXLEN-1)
printf (“堆栈溢出!”);
else
{
if (top= =0)
{
top++;
S [top]=x;
}
else
{
top=top+M;
S [top]=x;
}
}
}
//②出栈算法:
void pop (charx)
四.分析下述算法的功能
(1)返回结点*p的直接前趋结点地址。
(2)交换结点*p和结点*q(p和q的值不变)。
五.程序填空
(1)已知线性表中的元素是无序的,并以带表头结点的单链表作存储。试写一算法,删除表中所有大于min,小于max的元素,试完成下列程序填空。
Void delete (lklist head; datatype min, max)
scanf("%d",&n);
Conversion(n);
}
单元练习4
五.程序填空
假定用一个循环单链表表示一个循环队列,该队列只设一个队尾指针rear,试填空完成向循环队列中插入一个元素为x的结点的函数。
typedef struct queuenode// 定义队列的存储结构
{int data;
struct queuenode *next;
case 15: printf("%c",'F');break;
}
stacknode *p=s.top;
s.top=s.top->next;
free(p);//出栈一个余数,收回一个结
}
printf("\n\n");
}
void main()
{
int n;
printf("\n\t\t请输入一个十进制正整数:");
解:
//入队算法:
void inqueqe(int x)
{ int temp;
if (count==n)
printf("队列上溢出\n");
else
{ count++
temp=(front+count)%n;
Queue[temp]=x
}
}
//出队算法:
int outqueue()
{ int temp;
}
return(n);
}
(5)有两个循环单向链表,链头指针分别为head1和head2,编写一个函数将链表head1链接到链表head2,链接后的链表仍是循环链表。
解://本题的算法思想是:先找到两链表的尾指针,将第一个链表的尾指针与第二个链表的头结点链接起来,使之成为循环的。函数如下:
node *link (node *head1, *head2)
{ListNode *p=L,*q;
if(L->next->data==X)
{
printf(“值为x的结点是第一个结点,没有直接前趋结点可以删除”);
return;
}
For(p->next->data!=X;q=p;p=p->next);//删除指针p所指向的结点
q->next=p->next;
delete p;
解:#include<stdio.h>
#include<stdlib.h>
typedef struct stacknode//定义栈的存储结构
{
int data;
struct stacknode *next;
}stacknode;
typedef struct
{
stacknode *top;//定义栈顶的指针
单元练习1
四.分析下面各程序段的时间复杂度
1 O(n*m)(2) O(n2)(3) O(1)(4)O(n) (5) O(n2)
五.根据二元组关系,画出对应逻辑图形的草图,指出它们属于何种数据结构。
1
属于集合
(2)B=(D,R),其中:
属于线性结构
(3)属于树结
(4)
属于图结构
(5) 属于树结
(6)单元练习2
解:
void Show(ListNode *P)
{ ListNode *t=P;
do
{ printf("%c",t->data);
t=t->rear;
}
while (t!=P);
}
(1)对给定的带头结点的单链表L,编写一个删除L中值为x的结点的直接前趋结点的算法。
解:
void delete(ListNode *L)
{ q=head->next;
while (p!=NULL)
{ if ((p->data<=min ) | | (p->data>=max)
{q=p; p=p->next; }
else
{ q->next=p->next;
delete (p);
p=q->next; }
}
}
(2)在带头结点head的单链表的结点a之后插入新元素x,试完成下列程序填空。
①C,B,A,D,E ②A,C,B,E,D
解:①IIIOOOIOIO
②IOIIOOIIOO
(2)求后缀表达式
1A^B^C/D
解:A B^C^ D /
2-A+B*C+D/E
解:0 A–B C * + D E / +
3A*(B+C)*D-E
解:A B C + * D * E -
4(A+B)*C-E/(F+G/H)-D
delete p;
}
else
{
p=head;
for(j=1;j<=i-2;j++)
p=p->next; // p指向要删除的结点的前一个结点
for(j=1;j<=k;j++)
{
q=p->next; // q指向要删除的结点
p->next=q->next;
delete q;
}
}
}
(3)有一个单向链表(不同结点的数据域值可能相同),其头指针为head,编写一个函数计算值域为x的结点个数。
return 0;//若栈为空返回0;否则出栈
else
Pop(s);
}
if (StackEmpty (s) )//调用判栈空函数
printf (“配对正确!”);//若栈空,说明配对正确,并返回1
else
printf (“配对错误!”);//配对错误返回0
}
(3)设计一个将十进正整数转换为十进制数的算法,并要求上机调试通过。
{ node *p,*q;
p=head1;
while(p->next!=head1)
p=p->next;
q=head2;
while(q->next!=head2)
q=q->next;
p->next=head2;
q->next=head1;
return (head1);
}
单元练习3
四.应用题
(1)设有一个栈,元素进栈的次序为:A,B,C,D,E,用I表示进栈操作,O表示出栈操作,写出下列出栈的操作序列。
{ rear=s; rear->next;}
else
{ head=rear->next;// 循环队列非空,则将s插到后面
rear->next=s;
rear=s;
rear->next=head;
}
}
六. 算法设计题
(1)设一个循环队列Queue,只有头指针front,不设尾指针,另设一个含有元素个数的记数器cont,试写出相应的入队算法和出队算法。
{
case 10: printf("%c",'A');break;
case 11: printf("%c",'B');break;
case 12: printf("%c",'C');break;
case 13: printf("%c",'D');break;
case 14: printf("%c",'E');break;
const MAXLEN=100;
int queue[MAXLEN];
int front,count; //定义队头和计数器count
①初始化队列
void init()
{
front=1;
count=0;
}
②判定队空
int QEmpty()
{
if (count==0)
return(1);
else
return(0);}
相关文档
最新文档