精心整理
{//出队,把头结点之后的元素摘下
Datatypet;
QueueNode*p;
if(EmptyQueue(Q))
Error(\
p=Q->rear->next->next;//p指向将要摘下的结点 x=p->data;//保存结点中数据 if(p==Q->rear) {//当队列中只有一个结点时,p结点出队后,要将队尾指针指向头结点 Q->rear=Q->rear->next;Q->rear->next=p->next;} else? Q->rear->next->next=p->next;//摘下结点p free(p);//释放被删结点 returnx; } (7)假设以数组Q[m]存放循环队列中的元素,同时设置一个标志tag,以tag==0和tag==1来区别在队头指针(front)和队尾指针(rear)相等时,队列状态为“空”还是“满”。试编写与此结构相应的插入(enqueue)和删除(dlqueue)算法。
【解答】
循环队列类定义
#include
template
//循环队列的类定义
精心整理
精心整理
voidEnQueue(Type&item); TypeDeQueue(); TypeGetFront();
voidMakeEmpty(){front=rear=tag=0;}
//置空队列
intIsEmpty()const{returnfront==rear&&tag==0;} //判队列空否 intIsFull()const{returnfront==rear&&tag==1;} //判队列满否 private: intrear,front,tag; Type*Q; intm; }
//队尾指针、队头指针和队满标志
//存放队列元素的数组 //队列最大可容纳元素个数
构造函数 template
插入函数 template
删除函数 template
读取队头元素函数 template
assert(!IsEmpty());
//判断队列是否不空,空则出错处理
//返回队头元素的值
returnQ[(front+1)%m];
(8)如果允许在循环队列的两端都可以进行插入和删除操作。要求: ①写出循环队列的类型定义;
②写出“从队尾删除”和“从队头插入”的算法。
[题目分析]用一维数组v[0..M-1]实现循环队列,其中M是队列长度。设队头指针front和队尾指针rear,约定front指向队头元素的前一位置,rear指向队尾元素。定义front=rear时为队空,(rear+1)%m=front为队满。约定队头端入队向下标小的方向发展,队尾端入队向下标大的方向发展。 精心整理
精心整理
(1)#defineM队列可能达到的最大长度 typedefstruct {elemtpdata[M]; intfront,rear; }cycqueue;
(2)elemtpdelqueue(cycqueueQ)
//Q是如上定义的循环队列,本算法实现从队尾删除,若删除成功,返回被删除元素,否则给出出错信息。
{if(Q.front==Q.rear){printf(“队列空”);exit(0);} Q.rear=(Q.rear-1+M)%M;//修改队尾指针。
return(Q.data[(Q.rear+1+M)%M]);//返回出队元素。 }//从队尾删除算法结束
voidenqueue(cycqueueQ,elemtpx) //Q是顺序存储的循环队列,本算法实现“从队头插入”元素x。 {if(Q.rear==(Q.front-1+M)%M){printf(“队满”;exit(0);) Q.data[Q.front]=x;//x入队列 Q.front=(Q.front-1+M)%M;//修改队头指针。 }//结束从队头插入算法。 (9)已知Ackermann函数定义如下: ①写出计算Ack(m,n)的递归算法,并根据此算法给出出Ack(2,1)的计算过程。 ②写出计算Ack(m,n)的非递归算法。 intAck(intm,n) {if(m==0)return(n+1); elseif(m!=0&&n==0)return(Ack(m-1,1)); elsereturn(Ack(m-1,Ack(m,m-1)); }//算法结束 (1)Ack(2,1)的计算过程 Ack(2,1)=Ack(1,Ack(2,0))//因m<>0,n<>0而得 =Ack(1,Ack(1,1))//因m<>0,n=0而得 =Ack(1,Ack(0,Ack(1,0)))//因m<>0,n<>0而得 =Ack(1,Ack(0,Ack(0,1)))//因m<>0,n=0而得 =Ack(1,Ack(0,2))//因m=0而得 =Ack(1,3)//因m=0而得 =Ack(0,Ack(1,2))//因m<>0,n<>0而得 =Ack(0,Ack(0,Ack(1,1)))//因m<>0,n<>0而得 =Ack(0,Ack(0,Ack(0,Ack(1,0))))//因m<>0,n<>0而得 =Ack(0,Ack(0,Ack(0,Ack(0,1))))//因m<>0,n=0而得 =Ack(0,Ack(0,Ack(0,2)))//因m=0而得 =Ack(0,Ack(0,3))//因m=0而得 =Ack(0,4)//因n=0而得 =5//因n=0而得
(2)intAckerman(intm,intn) {intakm[M][N];inti,j;
for(j=0;j {akm[i][0]=akm[i-1][1]; for(j=1;j 精心整理 akm[i][j]=akm[i-1][akm[i][j-1]]; } return(akm[m][n]); }//算法结束 (10)已知f为单链表的表头指针,链表中存储的都是整型数据,试写出实现下列运算的递归算法: ①求链表中的最大整数; ②求链表的结点个数; ③求所有整数的平均值。 #include }; classList{ private: }; } voidList::NewList(constintretvalue){ first=NULL;intvalue;ListNode*q; cout<<\; cin>>value; while(value!=retvalue){ //提示 //输入 //输入有效 //建立包含value的新结点 //建立链表,以输入retvalue结束 ListNode*first,current; intMax(ListNode*f); intNum(ListNode*f); floatAvg(ListNode*f,int&n); List():first(NULL),current(NULL){} ~List(){} ListNode*NewNode(constintitem); voidNewList(constintretvalue); voidPrintList(); //构造函数 //析构函数 //创建链表结点,其值为item //链表类 intdata; //结点数据 //结点指针 //构造函数 ListNode*link; //链表结点类 classListNode{ //定义在头文件\中 ListNode(constintitem):data(item),link(NULL){} public: //建立链表,以输入retvalue结束 //输出链表所有结点数据 //求链表所有数据的最大值 //求链表中数据个数 //求链表所有数据的平均值 //创建新链表结点 intGetMax(){returnMax(first);} intGetNum(){returnNum(first);} floatGetAvg(){returnAvg(first);} ListNode*List::NewNode(constintitem){ returnnewnode; ListNode*newnode=newListNode(item); q=NewNode(value); if(first==NULL)first=current=q; else{current->link=q;current=q;} //空表时,新结点成为链表第一个结点 //非空表时,新结点链入链尾 精心整理