首页 数据结构答案

数据结构答案

举报
开通vip

数据结构答案 第1章 绪论 习题 1.简述下列概念:数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、抽象数据类型。 2.试举一个数据结构的例子,叙述其逻辑结构和存储结构两方面的含义和相互关系。 3.简述逻辑结构的四种基本关系并画出它们的关系图。 4.存储结构由哪两种基本的存储方法实现? 5.选择题 (1)在数据结构中,从逻辑上可以把数据结构分成( )。 A.动态结构和静态结构 B.紧凑结构和非紧凑结构 C.线性结构和非线性结构 D.内部结构和外部结构 (2)与数据元素本身的形...

数据结构答案
第1章 绪论 习题 1.简述下列概念:数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、抽象数据类型。 2.试举一个数据结构的例子,叙述其逻辑结构和存储结构两方面的含义和相互关系。 3.简述逻辑结构的四种基本关系并画出它们的关系图。 4.存储结构由哪两种基本的存储 方法 快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载 实现? 5.选择题 (1)在数据结构中,从逻辑上可以把数据结构分成( )。 A.动态结构和静态结构 B.紧凑结构和非紧凑结构 C.线性结构和非线性结构 D.内部结构和外部结构 (2)与数据元素本身的形式、内容、相对位置、个数无关的是数据的( )。 A.存储结构 B.存储实现 C.逻辑结构 D.运算实现 (3)通常要求同一逻辑结构中的所有数据元素具有相同的特性,这意味着( )。 A.数据具有同一特点 B.不仅数据元素所包含的数据项的个数要相同,而且对应数据项的类型要一致 C.每个数据元素都一样 D.数据元素所包含的数据项的个数要相等 (4)以下说法正确的是( )。 A.数据元素是数据的最小单位 B.数据项是数据的基本单位 C.数据结构是带有结构的各数据项的集合 D.一些 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 面上很不相同的数据可以有相同的逻辑结构 (5)以下与数据的存储结构无关的术语是( )。 A.顺序队列 B. 链表 C. 有序表 D. 链栈 (6)以下数据结构中,( )是非线性数据结构 A.树 B.字符串 C.队 D.栈 6.试 分析 定性数据统计分析pdf销售业绩分析模板建筑结构震害分析销售进度分析表京东商城竞争战略分析 下面各程序段的时间复杂度。 (1)x=90; y=100;  while(y>0) if(x>100) {x=x-10;y--;} else x++; (2)for (i=0; i1 y=0; while(x≥(y+1)* (y+1)) y++; (1)O(1) (2)O(m*n) (3)O(n2) (4)O(log3n) (5)因为x++共执行了n-1+n-2+……+1= n(n-1)/2,所以执行时间为O(n2) (6)O( ) 第2章 线性表 1.选择题 (1)一个向量第一个元素的存储地址是100,每个元素的长度为2,则第5个元素的地址是( )。 A.110 B.108 C.100 D.120 (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个结点从小到大排序 (3) 向一个有127个元素的顺序表中插入一个新元素并保持原来顺序不变,平均要移动 的元素个数为( )。 A.8 B.63.5 C.63 D.7 (4)链接存储的存储结构所占存储空间( )。 A.分两部分,一部分存放结点值,另一部分存放表示结点间关系的指针 B.只有一部分,存放结点值 C.只有一部分,存储表示结点间关系的指针 D.分两部分,一部分存放结点值,另一部分存放结点所占单元数 (5)线性表若采用链式存储结构时,要求内存中可用存储单元的地址( )。 A.必须是连续的 B.部分地址必须是连续的 C.一定是不连续的 D.连续或不连续都可以 (6)线性表L在( )情况下适用于使用链式结构实现。 A.需经常修改L中的结点值 B.需不断对L进行删除插入 C.L中含有大量的结点 D.L中结点结构复杂 (7)单链表的存储密度( )。 A.大于1 B.等于1 C.小于1 D.不能确定 (8)将两个各有n个元素的有序表归并成一个有序表,其最少的比较次数是( )。 A.n B.2n-1 C.2n D.n-1 (9)在一个长度为n的顺序表中,在第i个元素(1≤i≤n+1)之前插入一个新元素时须向后移动( )个元素。 A.n-i B.n-i+1 C.n-i-1 D.i (10) 线性表L=(a1,a2,……an),下列说法正确的是( )。 A.每个元素都有一个直接前驱和一个直接后继 B.线性表中至少有一个元素 C.表中诸元素的排列必须是由小到大或由大到小 D.除第一个和最后一个元素外,其余每个元素都有一个且仅有一个直接前驱和直接后继。 (11) 若指定有n个元素的向量,则建立一个有序单链表的时间复杂性的量级是( )。 A.O(1) B.O(n) C.O(n2) D.O(nlog2n) (12) 以下说法错误的是( )。 A.求表长、定位这两种运算在采用顺序存储结构时实现的效率不比采用链式存储结构时实现的效率低 B.顺序存储的线性表可以随机存取 C.由于顺序存储要求连续的存储区域,所以在存储管理上不够灵活 D.线性表的链式存储结构优于顺序存储结构 (13) 在单链表中,要将s所指结点插入到p所指结点之后,其语句应为( )。 A.s->next=p+1; p->next=s; B.(*p).next=s; (*s).next=(*p).next; C.s->next=p->next; p->next=s->next; D.s->next=p->next; p->next=s; (14) 在双向链表存储结构中,删除p所指的结点时须修改指针( )。 A.p->next->prior=p->prior; p->prior->next=p->next; B.p->next=p->next->next; p->next->prior=p; C.p->prior->next=p; p->prior=p->prior->prior; D.p->prior=p->next->next; p->next=p->prior->prior; (15) 在双向循环链表中,在p指针所指的结点后插入q所指向的新结点,其修改指针的操作是( )。 A.p->next=q; q->prior=p; p->next->prior=q; q->next=q; B.p->next=q; p->next->prior=q; q->prior=p; q->next=p->next; C.q->prior=p; q->next=p->next; p->next->prior=q; p->next=q; D.q->prior=p; q->next=p->next; p->next=q; p->next->prior=q; 2.算法设计题 (1)将两个递增的有序链表合并为一个递增的有序链表。要求结果链表仍使用原来两个链表的存储空间, 不另外占用其它的存储空间。表中不允许有重复的数据。 void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc){ pa=La->next; pb=Lb->next; Lc=pc=La; //用La的头结点作为Lc的头结点 while(pa && pb){ if(pa->datadata){ pc->next=pa;pc=pa;pa=pa->next;} else if(pa->data>pb->data) {pc->next=pb; pc=pb; pb=pb->next;} else {// 相等时取La的元素,删除Lb的元素 pc->next=pa;pc=pa;pa=pa->next; q=pb->next;delete pb ;pb =q;} } pc->next=pa?pa:pb; //插入剩余段 delete Lb; //释放Lb的头结点} (2)将两个非递减的有序链表合并为一个非递增的有序链表。要求结果链表仍使用原来两个链表的存储空间, 不另外占用其它的存储空间。表中允许有重复的数据。 void union(LinkList& La, LinkList& Lb, LinkList& Lc, ) { pa = La->next; pb = Lb->next; // 初始化 Lc=pc=La; //用La的头结点作为Lc的头结点 Lc->next = NULL; while ( pa || pb ) { if ( !pa ) { q = pb; pb = pb->next; } else if ( !pb ) { q = pa; pa = pa->next; } else if (pa->data <= pb->data ) { q = pa; pa = pa->next; } else { q = pb; pb = pb->next; } q->next = Lc->next; Lc->next = q; // 插入 } delete Lb; //释放Lb的头结点} (3)已知两个链表A和B分别表示两个集合,其元素递增排列。请设计算法求出A与B的交集,并存放于A链表中。 void Mix(LinkList& La, LinkList& Lb, LinkList& Lc, ) { pa=la->next;pb=lb->next;∥设工作指针pa和pb; Lc=pc=La; //用La的头结点作为Lc的头结点 while(pa&&pb) if(pa->data==pb->data)∥交集并入结果表中。 { pc->next=pa;pc=pa;pa=pa->next; u=pb;pb=pb->next; delete u;} else if(pa->datadata) {u=pa;pa=pa->next; delete u;} else {u=pb; pb=pb->next; delete u;} while(pa){ u=pa; pa=pa->next; delete u;}∥ 释放结点空间 while(pb) {u=pb; pb=pb->next; delete u;}∥释放结点空间 pc->next=null;∥置链表尾标记。 delete Lb; ∥注: 本算法中也可对B表不作释放空间的处理 (4)已知两个链表A和B分别表示两个集合,其元素递增排列。请设计算法求出两个集合A和B 的差集(即仅由在A中出现而不在B中出现的元素所构成的集合),并以同样的形式存储,同时返回该集合的元素个数。 void Difference(LinkedList A,B,*n) ∥A和B均是带头结点的递增有序的单链表,分别存储了一个集合,本算法求两集合的差集,存储于单链表A中,*n是结果集合中元素个数,调用时为0 {p=A->next; ∥p和q分别是链表A和B的工作指针。 q=B->next; pre=A; ∥pre为A中p所指结点的前驱结点的指针。 while(p!=null && q!=null) if(p->datadata){pre=p;p=p->next;*n++;} ∥ A链表中当前结点指针后移。 else if(p->data>q->data)q=q->next; ∥B链表中当前结点指针后移。 else {pre->next=p->next; ∥处理A,B中元素值相同的结点,应删除。 u=p; p=p->next; delete u;} ∥删除结点 (5)设计算法将一个带头结点的单链表A分解为两个具有相同结构的链表B、C,其中B表的结点为A表中值小于零的结点,而C表的结点为A表中值大于零的结点(链表A的元素类型为整型,要求B、C表利用A表的结点)。 (6)设计一个算法,通过一趟遍历在单链表中确定值最大的结点。 ElemType Max (LinkList L ){ if(L->next==NULL) return NULL; pmax=L->next; //假定第一个结点中数据具有最大值 p=L->next->next; while(p != NULL ){//如果下一个结点存在 if(p->data > pmax->data) pmax=p; p=p->next; } return pmax->data; (7)设计一个算法,通过遍历一趟,将链表中所有结点的链接方向逆转,仍利用原表的存储空间。 void inverse(LinkList &L) { // 逆置带头结点的单链表 L p=L->next; L->next=NULL; while ( p) { q=p->next; // q指向*p的后继 p->next=L->next; L->next=p; // *p插入在头结点之后 p = q; } } (8)设计一个算法,删除递增有序链表中值大于mink且小于maxk的所有元素(mink和maxk是给定的两个参数,其值可以和表中的元素相同,也可以不同 )。 void delete(LinkList &L, int mink, int maxk) { p=L->next; //首元结点 while (p && p->data<=mink) { pre=p; p=p->next; } //查找第一个值>mink的结点 if (p) { while (p && p->datanext; // 查找第一个值 ≥maxk 的结点 q=pre->next; pre->next=p; // 修改指针 while (q!=p) { s=q->next; delete q; q=s; } // 释放结点空间 }//if } (9)已知p指向双向循环链表中的一个结点,其结点结构为data、prior、next三个域,写出算法change(p),交换p所指向的结点和它的前缀结点的顺序。 知道双向循环链表中的一个结点,与前驱交换涉及到四个结点(p结点,前驱结点,前驱的前驱结点,后继结点)六条链。 void Exchange(LinkedList p) ∥p是双向循环链表中的一个结点,本算法将p所指结点与其前驱结点交换。 {q=p->llink; q->llink->rlink=p; ∥p的前驱的前驱之后继为p p->llink=q->llink; ∥p的前驱指向其前驱的前驱。 q->rlink=p->rlink; ∥p的前驱的后继为p的后继。 q->llink=p; ∥p与其前驱交换 p->rlink->llink=q; ∥p的后继的前驱指向原p的前驱 p->rlink=q; ∥p的后继指向其原来的前驱 }∥算法exchange结束。 (10)已知长度为n的线性表A采用顺序存储结构,请写一时间复杂度为O(n)、空间复杂度为O(1)的算法,该算法删除线性表中所有值为item的数据元素。 [题目分析] 在顺序存储的线性表上删除元素,通常要涉及到一系列元素的移动(删第i个元素,第i+1至第n个元素要依次前移)。本题要求删除线性表中所有值为item的数据元素,并未要求元素间的相对位置不变。因此可以考虑设头尾两个指针(i=1,j=n),从两端向中间移动,凡遇到值item的数据元素时,直接将右端元素左移至值为item的数据元素位置。 void Delete(ElemType A[ ],int n) ∥A是有n个元素的一维数组,本算法删除A中所有值为item的元素。 {i=1;j=n;∥设置数组低、高端指针(下标)。 while(idata;top=top->link; B.top=top->link;x=top->link; C.x=top;top=top->link; D.x=top->link; (5)设有一个递归算法如下         int fact(int n) {  //n大于等于0              if(n<=0) return 1;              else return n*fact(n-1);        } 则计算fact(n)需要调用该函数的次数为( )。  A. n+1       B. n-1      C. n      D. n+2 (6)栈在 ( )中有所应用。 A.递归调用 B.函数调用 C.表达式求值 D.前三个选项都有 (7)为解决计算机主机与打印机间速度不匹配问题,通常设一个打印数据缓冲区。主机将要输出的数据依次写入该缓冲区,而打印机则依次从该缓冲区中取出数据。该缓冲区的逻辑结构应该是( )。 A.队列 B.栈 C. 线性表 D.有序表 (8)设栈S和队列Q的初始状态为空,元素e1、e2、e3、e4、e5和e6依次进入栈S,一个元素出栈后即进入Q,若6个元素出队的序列是e2、e4、e3、e6、e5和e1,则栈S的容量至少应该是( )。 A.2 B.3 C.4 D. 6 (9)在一个具有n个单元的顺序栈中,假设以地址高端作为栈底,以top作为栈顶指针,则当作进栈处理时,top的变化为( )。 A.top不变 B.top=0 C.top-- D.top++ (10)设计一个判别表达式中左,右括号是否配对出现的算法,采用( )数据结构最佳。 A.线性表的顺序存储结构 B.队列 C. 线性表的链式存储结构 D. 栈 (11)用链接方式存储的队列,在进行删除运算时( )。 A. 仅修改头指针 B. 仅修改尾指针 C. 头、尾指针都要修改 D. 头、尾指针可能都要修改 (12)循环队列存储在数组A[0..m]中,则入队时的操作为( )。 A. rear=rear+1 B. rear=(rear+1)%(m-1) C. rear=(rear+1)%m D. rear=(rear+1)%(m+1) (13)最大容量为n的循环队列,队尾指针是rear,队头是front,则队空的条件是( )。 A. (rear+1)%n==front B. rear==front C.rear+1==front D. (rear-l)%n==front (14)栈和队列的共同点是( )。 A. 都是先进先出 B. 都是先进后出 C. 只允许在端点处插入和删除元素 D. 没有共同点 (15)一个递归算法必须包括( )。 A. 递归部分 B. 终止条件和递归部分 C. 迭代部分 D. 终止条件和迭代部分 (2)回文是指正读反读均相同的字符序列,如“abba”和“abdba”均是回文,但“good”不是回文。试写一个算法判定给定的字符向量是否为回文。(提示:将一半字符入栈)  根据提示,算法可设计为:  //以下为顺序栈的存储结构定义  #define StackSize 100 //假定预分配的栈空间最多为100个元素  typedef char DataType;//假定栈元素的数据类型为字符  typedef struct{   DataType data[StackSize];   int top;  }SeqStack;   int IsHuiwen( char *t)   {//判断t字符向量是否为回文,若是,返回1,否则返回0    SeqStack s;    int i , len;    char temp;    InitStack( &s);    len=strlen(t); //求向量长度    for ( i=0; i=’0’&&x<=’9’)||x==’.’) //拼数 if(x!=’.’) //处理整数 {num=num*10+(ord(x)-ord(‘0’)); scanf(“%c”,&x);} else //处理小数部分。 {scale=10.0; scanf(“%c”,&x); while(x>=’0’&&x<=’9’) {num=num+(ord(x)-ord(‘0’)/scale; scale=scale*10; scanf(“%c”,&x); } }//else push(OPND,num); num=0.0;//数压入栈,下个数初始化 case x=‘ ’:break; //遇空格,继续读下一个字符。 case x=‘+’:push(OPND,pop(OPND)+pop(OPND));break; case x=‘-’:x1=pop(OPND);x2=pop(OPND);push(OPND,x2-x1);break; case x=‘*’:push(OPND,pop(OPND)*pop(OPND));break; case x=‘/’:x1=pop(OPND);x2=pop(OPND);push(OPND,x2/x1);break; default: //其它符号不作处理。 }//结束switch scanf(“%c”,&x);//读入表达式中下一个字符。 }//结束while(x!=‘$’) printf(“后缀表达式的值为%f”,pop(OPND)); }//算法结束。 [算法讨论]假设输入的后缀表达式是正确的,未作错误检查。算法中拼数部分是核心。若遇到大于等于‘0’且小于等于‘9’的字符,认为是数。这种字符的序号减去字符‘0’的序号得出数。对于整数,每读入一个数字字符,前面得到的部分数要乘上10再加新读入的数得到新的部分数。当读到小数点,认为数的整数部分已完,要接着处理小数部分。小数部分的数要除以10(或10的幂数)变成十分位,百分位,千分位数等等,与前面部分数相加。在拼数过程中,若遇非数字字符,表示数已拼完,将数压入栈中,并且将变量num恢复为0,准备下一个数。这时对新读入的字符进入‘+’、‘-’、‘*’、‘/’及空格的判断,因此在结束处理数字字符的case后,不能加入break语句。 (5)假设以I和O分别表示入栈和出栈操作。栈的初态和终态均为空,入栈和出栈的操作序列可表示为仅由I和O组成的序列,称可以操作的序列为合法序列,否则称为非法序列。 ①下面所示的序列中哪些是合法的? A. IOIIOIOO B. IOOIOIIO C. IIIOIOIO D. IIIOOIOO ②通过对①的分析,写出一个算法,判定所给的操作序列是否合法。若合法,返回true,否则返回false(假定被判定的操作序列已存入一维数组中)。 ①A和D是合法序列,B和C 是非法序列。 ②设被判定的操作序列已存入一维数组A中。 int Judge(char A[]) //判断字符数组A中的输入输出序列是否是合法序列。如是,返回true,否则返回false。 {i=0; //i为下标。 j=k=0; //j和k分别为I和字母O的的个数。 while(A[i]!=‘\0’) //当未到字符数组尾就作。 {switch(A[i]) {case‘I’: j++; break; //入栈次数增1。 case‘O’: k++; if(k>j){printf(“序列非法\n”);exit(0);} } i++; //不论A[i]是‘I’或‘O’,指针i均后移。} if(j!=k) {printf(“序列非法\n”);return(false);} else {printf(“序列合法\n”);return(true);} }//算法结束。 [算法讨论]在入栈出栈序列(即由‘I’和‘O’组成的字符串)的任一位置,入栈次数(‘I’的个数)都必须大于等于出栈次数(即‘O’的个数),否则视作非法序列,立即给出信息,退出算法。整个序列(即读到字符数组中字符串的结束标记‘\0’),入栈次数必须等于出栈次数(题目中要求栈的初态和终态都为空),否则视为非法序列。 (6)假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾元素站点(注意不设头指针) ,试编写相应的置空队、判队空 、入队和出队等算法。  算法如下:  //先定义链队结构:  typedef struct queuenode{    Datatype data;    struct queuenode *next;   }QueueNode; //以上是结点类型的定义  typedef struct{    queuenode *rear;   }LinkQueue; //只设一个指向队尾元素的指针  (1)置空队   void InitQueue( LinkQueue *Q)    { //置空队:就是使头结点成为队尾元素     QueueNode *s;     Q->rear = Q->rear->next;//将队尾指针指向头结点     while (Q->rear!=Q->rear->next)//当队列非空,将队中元素逐个出队      {s=Q->rear->next;       Q->rear->next=s->next;       free(s);      }//回收结点空间    }  (2)判队空    int EmptyQueue( LinkQueue *Q)    { //判队空     //当头结点的next指针指向自己时为空队     return Q->rear->next->next==Q->rear->next;    }  (3)入队   void EnQueue( LinkQueue *Q, Datatype x)    { //入队     //也就是在尾结点处插入元素     QueueNode *p=(QueueNode *) malloc (sizeof(QueueNode));//申请新结点     p->data=x; p->next=Q->rear->next;//初始化新结点并链入     Q-rear->next=p;      Q->rear=p;//将尾指针移至新结点    }  (4)出队   Datatype DeQueue( LinkQueue *Q)    {//出队,把头结点之后的元素摘下     Datatype t;     QueueNode *p;     if(EmptyQueue( Q ))       Error("Queue underflow");     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);//释放被删结点     return x;    } (7)假设以数组Q[m]存放循环队列中的元素, 同时设置一个标志tag,以tag == 0和tag == 1来区别在队头指针(front)和队尾指针(rear)相等时,队列状态为“空”还是“满”。试编写与此结构相应的插入(enqueue)和删除(dlqueue)算法。 【解答】 循环队列类定义 #include template class Queue { //循环队列的类定义 public: Queue ( int=10 ); ~Queue ( ) { delete [ ] Q; } void EnQueue ( Type & item ); Type DeQueue ( ); Type GetFront ( ); void MakeEmpty ( ) { front = rear = tag = 0; } //置空队列 int IsEmpty ( ) const { return front == rear && tag == 0; } //判队列空否 int IsFull ( ) const { return front == rear && tag == 1; } //判队列满否 private: int rear, front, tag; //队尾指针、队头指针和队满标志 Type *Q; //存放队列元素的数组 int m; //队列最大可容纳元素个数 } 构造函数 template Queue:: Queue ( int sz ) : rear (0), front (0), tag(0), m (sz) { //建立一个最大具有m个元素的空队列。 Q = new Type[m]; //创建队列空间 assert ( Q != 0 ); //断言: 动态存储分配成功与否 } 插入函数 template void Queue :: EnQueue ( Type &item ) { assert ( ! IsFull ( ) ); //判队列是否不满,满则出错处理 rear = ( rear + 1 ) % m; //队尾位置进1, 队尾指针指示实际队尾位置 Q[rear] = item; //进队列 tag = 1; //标志改1,表示队列不空 } 删除函数 template Type Queue :: DeQueue ( ) { assert ( ! IsEmpty ( ) ); //判断队列是否不空,空则出错处理 front = ( front + 1 ) % m; //队头位置进1, 队头指针指示实际队头的前一位置 tag = 0; //标志改0, 表示栈不满 return Q[front]; //返回原队头元素的值 } 读取队头元素函数 template Type Queue :: GetFront ( ) { assert ( ! IsEmpty ( ) ); //判断队列是否不空,空则出错处理 return Q[(front + 1) % m]; //返回队头元素的值 } (8)如果允许在循环队列的两端都可以进行插入和删除操作。要求: ① 写出循环队列的类型定义; ② 写出“从队尾删除”和“从队头插入”的算法。 [题目分析] 用一维数组 v[0..M-1]实现循环队列,其中M是队列长度。设队头指针 front和队尾指针rear,约定front指向队头元素的前一位置,rear指向队尾元素。定义front=rear时为队空,(rear+1)%m=front 为队满。约定队头端入队向下标小的方向发展,队尾端入队向下标大的方向发展。 (1)#define M 队列可能达到的最大长度 typedef struct { elemtp data[M]; int front,rear; } cycqueue; (2)elemtp delqueue ( cycqueue Q) //Q是如上定义的循环队列,本算法实现从队尾删除,若删除成功,返回被删除元素,否则给出出错信息。 { if (Q.front==Q.rear) {printf(“队列空”); exit(0);} Q.rear=(Q.rear-1+M)%M; //修改队尾指针。 return(Q.data[(Q.rear+1+M)%M]); //返回出队元素。 }//从队尾删除算法结束 void enqueue (cycqueue Q, elemtp x) // 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)的非递归算法。 int Ack(int m,n) {if (m==0) return(n+1); else if(m!=0&&n==0) return(Ack(m-1,1)); else return(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)int Ackerman( int m, int n) {int akm[M][N];int i,j; for(j=0;j //定义在头文件"RecurveList.h"中 class List; class ListNode { //链表结点类 friend class List; private: int data; //结点数据 ListNode *link; //结点指针 ListNode ( const int item ) : data(item), link(NULL) { } //构造函数 }; class List { //链表类 private: ListNode *first, current; int Max ( ListNode *f ); int Num ( ListNode *f ); float Avg ( ListNode *f, int& n ); public: List ( ) : first(NULL), current (NULL) { } //构造函数 ~List ( ){ } //析构函数 ListNode* NewNode ( const int item ); //创建链表结点, 其值为item void NewList ( const int retvalue ); //建立链表, 以输入retvalue结束 void PrintList ( ); //输出链表所有结点数据 int GetMax ( ) { return Max ( first ); } //求链表所有数据的最大值 int GetNum ( ) { return Num ( first ); } //求链表中数据个数 float GetAvg ( ) { return Avg ( first ); } //求链表所有数据的平均值 }; ListNode* List :: NewNode ( const int item ) { //创建新链表结点 ListNode *newnode = new ListNode (item); return newnode; } void List :: NewList ( const int retvalue ) { //建立链表, 以输入retvalue结束 first = NULL; int value; ListNode *q; cout << "Input your data:\n"; //提示 cin >> value; //输入 while ( value != retvalue ) { //输入有效 q = NewNode ( value ); //建立包含value的新结点 if ( first == NULL ) first = current = q; //空表时, 新结点成为链表第一个结点 else { current->link = q; current = q; } //非空表时, 新
本文档为【数据结构答案】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_928695
暂无简介~
格式:doc
大小:1MB
软件:Word
页数:56
分类:理学
上传时间:2012-04-14
浏览量:852