算法和数据结构C语言版课后习题集答案解析(机械工业出版社)第34章习题集参考答案解析

合集下载

算法与数据结构C语言习题参考答案章

算法与数据结构C语言习题参考答案章

绪论1.将下列复杂度由小到大重新排序:A.2n B.n C.n5D.10 000 E.n*log2 n答10 000< n*log2n< n5< 2n < n2.将下列复杂度由小到大重新排序:A.n*log2n B.n + n2 + n3C.24D.n0.5答24< n0.5< n*log2 n < n + n2 + n33.用大“O”表示法描述下列复杂度:A.5n5/2 + n2/5 B.6*log2n + 9nC.3n4+ n* log2n D.5n2 + n3/2答A:O n5/2B:O n C:O n4D:O n24.按照增长率从低到高的顺序排列以下表达式:4n2 ; log3n; 3n ; 20n ; 2000 ; log2n ; n2/3..又n应排在第几位答按照增长率从低到高依次为:2000; log3n; log2n ; n2/3 ; 20n ; 4n2 ; 3n..n的增长率比它们中的每一个都要大;应排在最后一位..5. 计算下列程序片断的时间代价:int i=1;whilei<=n{printf“i=%d\n”;i;i=i+1;}答循环控制变量i从1增加到n;循环体执行n次;第一句i的初始化执行次数为1;第二句执行n次;循环体中第一句printf执行n次;第二句i从1循环到n;共执行n次..所以该程序段总的时间代价为:Tn = 1 + n + 2n = 3n+ 1 = On6. 计算下列程序片断的时间代价:int i=1;whilei<=n{int j=1;whilej<=n{int k=1;whilek<=n{printf“i=%d;j=%d;k=%d\n”;I;j;k;k=k+1;}j=j+1;}i=i+1;}答循环控制变量i从1增加到n;最外层循环体执行n次;循环控制变量j从1增加到n;中间层循环体执行n次;循环控制变量k从1增加到n;最内层循环体执行n次;所以该程序段总的时间代价为:Tn = 1 + n + n{1 + n + n1 + n + 2n +1 +1 +1}+ 1= 3n3 + 3n2 +4n +2= On32. 线性表1.试写一个插入算法int insertPost_seqpalist; p; x ;在palist所指顺序表中;下标为p的元素之后;插入一个值为x的元素;返回插入成功与否的标志..答数据结构采用2.1.2节中顺序表定义..int insertPost_seqPseqList palist; int p; DataType x {/* 在palist所指顺序表中下标为p的元素之后插入元素x */int q;if palist->n >= palist-> MAXNUM { /* 溢出*/printf“Overflow\n”;return 0;}if p<0 || p>palist->n-1 { /* 不存在下标为p的元素*/printf“N ot exist \n”; return 0;}forq=palist->n - 1; q>=p+1; q-- /* 插入位置及之后的元素均后移一个位置*/palist->elementq+1 = palist->elementq;palist->elementp+1 = x; /* 插入元素x */palist->n = palist->n + 1; /* 元素个数加1 */return 1;}2试写一个删除算法deleteV_seqpalist; x ;在palist所指顺序表中;删除一个值为x的元素;返回删除成功与否的标志..答数据结构采用2.1.2节中顺序表定义..int deleteV_seqPseqList palist; p; DataType x {/* 在palist所指顺序表中删除值为x的元素*/int p;q;forp=0;p<n;p++ /*查找值为x的元素的下标*/ifx==palist->elementp{forq=p; q<palist->n-1; q++ /* 被删除元素之后的元素均前移一个位置*/palist->elementq = palist->elementq+1;palist->n = palist->n - 1; /* 元素个数减1 */return 1 ;}return 0;}3. 设有一线性表e = e0; e1 ; e2 ; …; e n 1 ;其逆线性表定义为e = e n 1 ; …; e2 ; e1 ;e0..请设计一个算法;将用顺序表表示的线性表置逆;要求逆线性表仍占用原线性表的空间..答数据结构采用2.1.2节中顺序表的定义..思路考虑对数组element 进行置逆;即把第一个元素和最后一个元素换位置;把第二个元素和倒数第二个元素换位置……..注意这种调换的工作只需对数组的前一半元素进行;所以设置整数变量count用于存放数组长度的一半的值..大家可以考虑一下:为什么不能对整个数组进行如上的对元素“换位置”的工作提示:这样会将本来已经置逆的线性表又置逆回来;即又变成了原来的表..顺序表的置逆算法void rev_seqPSeqList palist{DataType x;int count; i;if palist->n == 0 || palist->n == 1 return; /*空表或只有一个元素;直接返回*/count = palist->n / 2;for i = 0; i < count; i++{ /*只需调换半个表的元素*/x = palist->elementi;palist->elementi = palist->elementpalist->n 1 i;palist->elementpalist->n 1 i = x;}}代价分析该算法中包含一个for循环;其循环次数为n/2..因此;算法的时间代价为On..4. 已知长度为n的线性表A采用顺序存储结构;请写一算法;找出该线性表中值最小的数据元素.. 答数据结构采用2.1.2节中顺序表定义..思路设置变量min;遍历整个表;不断更新当前已经经历过的元素的最小值即可..为方便起见;事先假设表不为空..算法DataType min_seqPSeqList palist{ /*求非空顺序表中的最小数据元素*/DataType min;int i;min = palist->element0; /*初始化min*/for i = 1; i < palist->n; i++ /*min中保存的总是当前的最小数据*/if min > palist->elementimin = palist->elementi;return min;}代价分析该算法访问顺序表中每个元素各一次;时间代价为On..讨论读者可以试图对上面的算法进行修改;使返回的值不是最小元素的值而是它的下标..5. 已知线性表A的长度为n;并且采用顺序存储结构..写一算法;删除线性表中所有值为x的元素.. 答数据结构采用2.1.2节中顺序表的定义..思路为了减少移动次数;可以采用快速检索的思想;用两个变量i; j记录顺序表中被处理的两端元素的下标;开始时i = 0;j = n 1;边检索第i个元素边增加i;直到找到一个元素值等于x;再边检索第j个元素边减少j;直到找到一个元素值不等于x;把下标为j的元素移到下标为i的位置后重复上述过程;直到i≥j..另用一变量count记录删除了多少个元素..算法void delx_seqPSeqList p; DataType x{/*删除顺序表中所有值为x的元素;新顺序表可能不保持原有顺序*/int i = 0; j = p->n 1; count = 0; /*i定位于顺序表开始处;j定位于顺序表最后*/while i < j {if p->elementi == x { /*找到了一个要删除的元素*/while p->elementj == x && i = j {/*从后往前找不会被删除的元素;当i; j相等时退出循环;count记录从后往前找的过程中遇到了多少个要删的元素*/j ;count++;}if i = = j {p->n = p->n count 1;return;}else{p->elementi = p->elementj;count++;j ;}}i++;}p->n = p->n count;if p->elementi == x p >n ;}代价分析该算法访问顺序表中每个元素各一次;时间代价为O n..讨论这个算法使用了一点技巧使得在中间删除元素时;避免了最后一串元素的移动..但是;它破坏了原来线性表中元素之间的顺序关系..如果需要保持原来的顺序应该怎样做这里提供一种可行的思路:从前向后遍历表;如果元素不是x;则继续向后;如果元素是x;则寻找其后第一个不是x的元素;将这两个元素互换..具体算法请读者自己实现..6.写一算法;在带头结点的单链表llist中;p所指结点前面插入值为x的新结点;并返回插入成功与否的标志..答数据结构采用2.1.3节中单链表定义..思想:由于在单链表中;只有指向后继结点的指针;所以只有首先找到p所指结点的前驱结点;然后才能完成插入..而找p所指结点的前驱结点;只能从单链表的第一个结点开始;使用与locate_link 类似的方式进行搜索..算法:int insertPre_linkLinkList llist;PNode p;DataType x{/* 在llist带头结点的单链表中;p所指结点前面插入值为x的新结点*/PNode p1;ifllist==NULL return 0;p1=llist;whilep1=NULL&&p1->link=pp1=p1->link; /*寻找p所指结点的前驱结点*/ifp1=NULL return 0;PNode q=PNodemallocsizeofstruct Node;/*申请新结点*/ifq=NULL {printf“Out of space\n”;return 0;}q->info=x;q->link=p1->link;p1->link=q;return 1;}7.写一算法;在带头结点的单链表llist中;删除p所指的结点;并返回删除成功与否的标志..答数据结构采用2.1.3节中单链表定义..思想:由于在单链表中;只有指向后继结点的指针;所以只有首先找到p所指结点的前驱结点;然后才能完成删除..而找p所指结点的前驱结点;只能从单链表的第一个结点开始;使用与locate_link 类似的方式进行搜索..int deleteP_linkLinkList llist;PNode p{/* 在llist带头结点的单链表中;删除p所指的结点*/PNode p1;ifllist==NULLreturn Null;p1=llist;whilep1=NULL&&p1->link=pp1=p1->link; /*寻找p所指结点的前驱结点*/ifp1=NULLreturn 0;p1->link=p->link;freep; /* 删除结点p */return 1;}8. 已知list是指向无头结点的单链表的指针变量;写出删除该链表下标为i的第i+1个结点的算法..答数据结构采用2.1.3节中单链表定义..思路依次遍历表中的每一个结点并计数;到第i+1个结点时实行删除..由于链表是无头结点的;所以在删除第一个结点时要特别注意..算法int deleteindex_link_noheadLinkList * pllist; int i {/*删除单链表中下标为i的结点..删除成功返回TRUE;否则返回FALSE..*/int j;PNode p; q;if *pllist == NULL || i < 0 return FALSE;if i = = 0 { /*如果需要删除第一个结点*/q = *pllist;*pllist = *pllist->link;freeq;return TRUE;}p = *pllist;j = 0;while p->link = NULL && j < i 1 { /*寻找下标为i 1的结点的地址*/ p = p->link;j++;}if p->link == NULL return FALSE; /*此元素不存在*/q = p->link;p->link = q->link;freeq;return TRUE;}代价分析该算法访问单链表中前面i个结点;时间代价为Oi;最大不超过On..讨论如果函数参数不是LinkList *类型而是LinkList类型;在删除i=0的结点时;程序不能正确实现;其原因请读者思考考虑C语言的参数传递方式..如果单链表带表头结点;重写本题的算法..比较这两个算法;是否能体会到表头结点的作用..9. 已知list是指向无头结点的单链表的指针变量;写出删除该链表中从下标为i的第i+1个结点开始的连续k个结点的算法..答数据结构采用2.1.3节单链表定义..思路这道题与上题相似;只需要增加计数即可..要注意的是应该判断给出的i和k是否合理;是不是会超出链表长度..算法int del_link_noheadLinkList * pllist; int i; int k {/*删除单链表中从下标i开始的k个结点..删除成功返回TRUE;否则返回FALSE..*/int j;PNode p; q;if *pllist == NULL || i < 0 || k <= 0 return FALSE;if i = = 0 { /*如果需要删除从第一个结点开始的k个结点*/for j = 0; j < k && *pllist = NULL; j++ {q = *pllist;*pllist = *pllist->link;freeq;}return TRUE;}p = *pllist;j = 0;while p->link = NULL && j < i 1 { /*寻找下标为i 1的结点的地址*/p = p->link;j++;}if p->link == NULL return FALSE; /*第i个结点不存在*/for j = 0; j < k && p->link = NULL; j++ {q = p->link;p->link = q->link;freeq;}return TRUE;}代价分析该算法访问单链表中前面i+k个结点;时间代价为Oi+k;最大不超过On..13. 请设计一个算法;求出循环表中结点的个数..答数据结构采用不带头结点的循环链表..struct Node;typedef struct Node * PNode;struct Node{DataType info;PNode link;};typedef struct Node * LinkList;思路遍历整个循环链表;同时计数即可..错误算法int countLinkList clist{int count;PNode p; q;p = clist;q = p->link;if clist == NULL return 0; /*如果是空表*/count = 1;while q = p{q = q->link;count++;}return count;}错误:如果clist是一个空表;那么第5行的语句“q = p->link;”是非法的..分析:应把第6行语句用下划线表示提前1行或2行..一定要放在语句“q = p->link;”之前..缺点:增加局部变量p..分析:这样做没有必要;因为p的初值置为clist;在程序中并没有对p做其他修改;所以程序中不需要引入p而直接使用clist即可..算法int countLinkList clist{int count;PNode q;if clist == NULL return 0; /*如果是空表*/q = clist->link;count = 1;while q = clist{q = q->link;count++;}return count;}代价分析该算法访问循环链表中每个结点各一次;时间代价为On..4. 栈与队列1. 写一个递归算法来把整数字符串转换为整数..例:“43567”→43567..答思路先递归调用本算法转换除去末位外剩余的字符串;结果乘以10..再转换末位..将两结果相加即为所求..算法int stringToInt1char * s; int start; int end {/*把整数字符串s中从start到end的部分转换为整数*/if start > end return 1; /*转换失败*/if start == end return send '0'; /*只有一个字符;直接转换*/return stringToInt1s; start; end 1 * 10 + send '0'; /*先转换其他位;再转换末位*/}int stringToIntchar * s { /*把整数字符串s转换为整数*/int i = 0;while si = '\0' i++; /*计算字符串的长度*/return stringToInt1s; 0; i 1;}代价分析设n为字符串的长度..该算法访问每个字符各一次;时间代价为On;计算字符串的长度的时间代价也为On..故总的时间代价为On..递归算法需要栈的支持;栈的大小与递归调用的深度成正比..所以实际空间开销为On..2. 编写一个算法;对于输入的十进制非负整数;将它的二进制表示打印出来..答数据结构采用4.1.2节中栈的顺序表示..思路将输入的十进制数字反复除以2;直到它变为0..将每次的数字模2的余数入栈..栈中存放的就是所要求的二进制表示..再将栈中的元素依次弹出打印即可..算法void print_binint dec_number {/*将十进制非负整数转化为二进制数打印出来*/PSeqStack pastack; int temp = dec_number; if temp < 0 {printf"Error\n"; return;}pastack = createEmptyStack_seq; /*建立一个空栈*/ if pastack == NULL return; while temp > 0 {push_seqpastack; temp % 2; temp /= 2;}whileisEmptyStack_seqpastack {printf"%d"; top_seqpastack; pop_seqpastack;}freepastack;}代价分析设输入的十进制数字为n ;则算法的时间代价为O n 2log ..空间代价主要是栈的大小;为O n 2log .. 3.写一个算法:PSeqStack createEmptyStack_seq int m 创建一个空栈..数据结构采用4.1.2节中栈的顺序表示..PSegStack createEmptyStack_seqint m{ /* 创建一个空栈 */PSeqStack pastack = PSeqStackmallocsizeofstruct SeqStack; if pastack=NULL{ pastack ->s = DataType*mallocsizeofDataType*m;if pastack ->s{pastack ->MAXNUM=m; pastack ->t= -1;/* 栈顶变量赋值为-1 */return pastack ; }else free pastack; }printf “Out of space\n”; /* 存储分配失败 */return NULL;}4;写一个算法:int isEmptyStack_seq PSeqStack pastack 判断pastack所指的栈是否为空栈..数据结构采用4.1.2节中栈的顺序表示..int isEmptyStack_seqPSeqStack pastack{/* 判断pastack所指的栈是否为空栈*/ifpastack->t == -1 return 1;else return 0;}8. 假设以循环链表表示队列;并且只设一个指针指向队尾元素结点注意不设队头指针;试编写相应的创建空队列、入队列和出队列的算法..答数据结构采用不带头结点的循环链表表示队列..struct Node;typedef struct Node * PNode;struct Node {DataType info;PNode link;};struct ClinkQueue { /*循环链表表示的队列类型*/PNode r; /*尾指针*/}typedef struct ClinkQueue * PClinkQueue; /*指向循环链表表示的队列的指针类型*/ 思路与队列的单链表表示相似;但节省了指向队头的指针变量;所以在需要找表头结点时必须通过表尾指针进行..算法PClinkQueue createEmptyQueue_clink { /*创建空队列*/PClinkQueue pcqu = PClinkQueuemallocsizeofstruct ClinkQueue;pcqu->r = NULL;return pcqu;}void enQueue_clinkPClinkQueue pcqu; DataType x { /*进队列*/PNode p;p = PNodemallocsizeofstruct Node;p->info = x;if pcqu->r == NULL {pcqu->r = p;p->link = p;return;} /*进空队列;即往空队列中加入第一个结点*/p->link = pcqu->r->link;pcqu->r->link = p;pcqu->r = p;}void deQueue_clinkPClinkQueue pcqu { /*出队列*/PNode p;if pcqu->r == NULL { /*是空队列*/printf"Underflow\n";return;}if pcqu->r->link == pcqu->r { /*只有一个元素的队列*/freepcqu->r;pcqu->r = NULL;return;}p = pcqu->r->link; /*指向队头*/pcqu->r->link = p->link;freep;}代价分析上述几个算法都不包含循环;只有常数条语句;因此每个算法的时间代价均为O1..讨论本题可以看成队列的循环表实现..5. 二叉树与树1. 写一个算法来计算给定二叉树的叶结点数..答数据结构采用5.1.3节中二叉树的链接表示..算法int num_of_leavesBinTree t { /*计算二叉树的叶结点个数*/if t = = NULL return 0; /*空树;返回0*/if t->llink = = NULL && t->rlink = = NULL return 1; /*根结点是树叶;返回1*/return num_of_leavest->llink + num_of_leavest->rlink;/*返回“左子树的叶结点数+右子树的叶结点数”*/}代价分析该算法访问每个结点各一次;时间代价为On..空间代价为Oh..2. 假设二叉树采用链接方法存储;编写一个计算一棵二叉树t的高度的函数..数据结构采用5.1.3节中二叉树的链接表示..思路对一棵二叉树t;考察它左右子树的高度;取其中大的一个;再加1即为t的高度..算法int depthBinTree t{PBinTreeNode pbtree;int dl; dr;pbtree = t;if pbtree = = NULL{return 1;}dl = depthpbtree->llink;dr = depthpbtree->rlink;return dl > dr dl : dr + 1;}代价分析设树中的结点个数为n;递归访问次数只可能是n..所以;时间代价为On..空间代价为Oh..h为二叉树的高度..6. 设计一个程序;根据二叉树的先根序列和对称序序列创建一棵用左右指针表示的二叉树..答数据结构采用5.1.3节中二叉树的链接表示..思路二叉树的先根序列和对称序序列;用两个数组preorder和inorder存放..先根序列的第一个元素的值preorder0应为二叉树的根上的元素值;在另一个数组中查到此值;设为inorder k..此时;数组preorder中从preorder1到preorder k的序列长度为k和数组inorder中从inorder0到inorder k 1长度为k的序列;恰好分别是根结点左子树k个结点的先根序列和对称序序列..数组preorder中从preorder k+1到preorder n 1的序列长度为n k 1和数组inorder中从inorder k+1到inorder n 1长度为n k 1的序列;恰好分别是根结点左子树n k 1个结点的先根序列和对称序序列..根据上述分析;算法先创建根结点;再递归调用自己两次来分别创建左右子树..int create_BTreePBinTree pbtree; DataType * preorder; DataType * inorder; int n{/*根据先根序列preorder和对称序序列inorder长度为n创建二叉树pbtree..对于正确的先根序列和对称序序列;算法返回TRUE;否则返回FALSE..*/int i; k;int tag1; tag2;if n = = 0 {*pbtree = NULL;return TRUE;}for i = 0; i < n; i++if inorderi = = preorder0break;if i = = n {*pbtree = NULL;return FALSE; /*输入的先根序列或对称序序列有误;创建失败*/ }k = i;*pbtree = PBinTreeNodemallocsizeofstruct BinTreeNode;*pbtree->info = preorder0;tag1 = create_BTree&*pbtree->llink; preorder + 1; inorder; k;/*递归调用本算法创建左子树*/tag2 = create_BTree&*pbtree->rlink; preorder + k + 1; inorder + k + 1; n k 1;/*递归调用本算法创建右子树*/if tag1 = = TRUE && tag2 = = TRUE return TRUE;return FALSE; /*二叉树创建成功当且仅当其左右子树都创建成功*/ }代价分析最坏的情况是;每个非叶结点只有左子树..这时两个数组之间需要比较n+n-1+…+1=On2次..所以;该算法的时间代价为On2..空间代价主要包括:存放二叉树的空间On和用于递归调用的栈空间不超过On..7. 试设计树的子表表示法的存储结构;并给出在这种表示基础上主要运算的实现算法..答数据结构struct EdgeNode /*边表中结点的定义*/{int nodeposition; /*子结点位置*/struct EdgeNode * link; /*下一个边的指针*/};struct ChiTreeNode /*结点的定义*/{DataType info; /*结点本身信息*/struct EdgeNode * children; /*到子结点的边表*/};struct ChiTree /*树的定义*/{struct ChiTreeNode nodelistMAXNUM; /*结点表*/int root; /*根的位置*/int n; /*结点的个数*/ };typedef struct ChiTree * PChiTree;算法创建空树PChiTree CreateNullTree_chitreevoid{PChiTree p;p = PChiTreemallocsizeofstruct ChiTree;if p = = NULLprintf"Out of space\n";else{p->n=0;p->root = 1;}return p;}判断树是否为空int isNull_chitree PChiTree t{return t->n = = 0;}返回非空树的根结点的下标DataType root_chitree PChiTree t{return t->root;}返回下标为p的结点的父结点的下标int parent_chitree PChiTree t; int p{int i;struct EdgeNode * v;if p < 0 || p >= t->n return 1;for i = 0; i < t->n; i++{v = t->nodelisti.children;while v = NULLif v->nodeposition = = preturn i;elsev = v->link;}return 1;}返回下标为p的结点的最左子结点的下标int leftChild_chitreePParTree t; int p{struct EdgeNode * v;if p < 0 || p >= t->n return 1;v = t->nodelisti.children;if v = = NULL return 1;return v->nodeposition;}返回下标为p的结点的右兄弟结点的下标int rightSibling_chitreePParTree t; int p{int i;struct EdgeNode * v;if p < 0 || p >= t->n return 1; /*没有下标为p的结点*/for i = 0; i < t->n; i++ /*for循环每次检查结点下标中一个元素*/{v = t->nodelisti.children;while v = NULL /*每次循环检查结点i的边表中的一个元素*/if v->nodeposition = = pifv->link = = NULLreturn 1; /*没有右兄弟结点*/elsereturn v->link->nodeposition; /*返回右兄弟结点在结点表中的位置*/ elsev=v->link;}return 1; /*没有右兄弟结点*/}代价分析这是一个两重循环程序;外层循环最多执行n次;内层循环对每个结点的子结点进行检查;子结点的个数最大可能与n接近;所以表面看来这是一个n2阶的时间代价;但是;仔细分析内层的循环体;可以看出内层循环最多对树中的每条边执行一次;由于树中边的个数与结点的个数成正比;所以时间代价仍然是On..补充题:1. 试设计完全二叉树的顺序表示法的存储结构;并给出在这种表示基础上主要运算的实现算法.. 答数据结构struct SeqBTree{DataType nodelistMAXNODE;int n; /*完全二叉树的结点个数*/};typedef struct SeqBTree * PSeqBTree;算法判断二叉树是否为空int isNull_seqPSeqBTree t{return t->n = = 0;}返回非空二叉树的根结点的下标int root_seqPSeqBTree t{return 0;}返回下标为p的结点的父结点的下标int parent_seqPSeqBTree t; int p{if p < 0 || p >= t->n return 1;return p 1 / 2;}返回下标为p的结点的左子结点的下标int leftChild_seqPSeqBTree t; int p{if p < 0 || p >= t->n return 1;return 2*p + 1;}返回下标为p的结点的右子结点的下标int rightChild_seqbtreePSeqBTree t; int p{if p < 0 || p >= t->n return 1;return 2 * p + 1;}2. 试设计二叉树的左右指针表示法的存储结构;并给出在这种表示基础上主要运算的实现算法.. 答数据结构struct BinTreeNode;typedef struct BinTreeNode * PBinTreeNode;struct BinTreeNode {int info;PBinTreeNode llink;PBinTreeNode rlink;};typedef struct BinTreeNode * BinTree;算法判断二叉树是否为空int isNull_btreeBinTree t{return t = = NULL;}返回非空二叉树的根结点的地址PBinTreeNode root_btreeBinTree t{return t;}返回二叉树t中结点p的父结点的地址PBinTreeNode parent_btreePBinTreeNode p; BinTree t{PBinTreeNode r;if p = = NULL return NULL;if p = = t || t = = NULL return NULL;if t->llink = = p || t->rlink = = p return t;r = parent_btreep; t->llink; /*递归调用*/if r = NULL return r;r = parent_btreep; t->rlink; /*递归调用*/if r = NULL return r;return NULL;}返回结点p的左子结点的地址PBinTreeNode leftChild_btreePBinTreeNode p{if p = = NULL return NULL;return p->llink;}返回结点p的右子结点的地址PBinTreeNode rightChild_btreePBinTreeNode p{if p = = NULL return NULL;return p->rlink;}。

算法与数据结构习题及参考答案

算法与数据结构习题及参考答案

算法与数据结构习题及参考答案一、选择题1. 在算法分析中,时间复杂度表示的是:A. 算法执行的时间B. 算法的运行速度C. 算法执行所需的操作次数D. 算法的内存消耗答案:C2. 哪种数据结构可以在常数时间内完成插入和删除操作?A. 数组B. 栈C. 队列D. 链表答案:B3. 单链表的逆置可以使用哪种算法实现?A. 冒泡排序B. 归并排序C. 快速排序D. 双指针法答案:D4. 常用的查找算法中,哪种算法的时间复杂度始终为O(log n)?A. 顺序查找B. 二分查找C. 广度优先搜索D. 深度优先搜索答案:B5. 哪种排序算法的时间复杂度最坏情况下仍为O(n log n)?A. 冒泡排序B. 插入排序C. 快速排序D. 堆排序答案:C二、填空题1. 下面哪个数据结构先进先出?A. 栈B. 队列C. 堆D. 链表答案:B2. 在快速排序的基本步骤中,需要选取一个元素作为________。

答案:枢纽元素3. 广度优先搜索使用的数据结构是________。

答案:队列4. 二分查找是基于_________的。

答案:有序数组5. 哈希表的查找时间复杂度为_________。

答案:O(1)三、解答题1. 请简要说明冒泡排序算法的原理及时间复杂度。

答:冒泡排序是一种简单直观的排序算法。

它的基本思想是通过相邻元素之间的比较和交换来将最大(或最小)的元素逐渐“冒泡”到数列的一端。

冒泡排序的过程如下:1)比较相邻的元素,如果前面的元素大于后面的元素,则交换它们的位置;2)对每一对相邻元素重复进行比较和交换,直到最后一对元素;3)针对剩下的元素重复上述步骤,直到整个数列有序。

冒泡排序的时间复杂度为O(n^2),其中n为待排序数列的长度。

在最坏情况下,冒泡排序需要进行n-1次比较和交换操作,因此时间复杂度为O(n^2)。

在最好情况下,如果待排序数列已经有序,冒泡排序只需进行n-1次比较,没有交换操作,时间复杂度为O(n)。

数据结构(c语言版)课后习题答案完整版

数据结构(c语言版)课后习题答案完整版

数据结构(c语言版)课后习题答案完整版数据结构(C语言版)课后习题答案完整版一、数据结构概述数据结构是计算机科学中一个重要的概念,用来组织和存储数据,使之可以高效地访问和操作。

在C语言中,我们可以使用不同的数据结构来解决各种问题。

本文将提供完整版本的C语言数据结构的课后习题答案。

二、顺序表1. 顺序表的定义和基本操作顺序表是一种线性表,其中的元素在物理内存中连续地存储。

在C 语言中,我们可以通过定义结构体和使用指针来实现顺序表。

以下是顺序表的一些基本操作的答案:(1)初始化顺序表```ctypedef struct{int data[MAX_SIZE];int length;} SeqList;void InitList(SeqList *L){L->length = 0;}```(2)插入元素到顺序表中```cbool Insert(SeqList *L, int pos, int elem){if(L->length == MAX_SIZE){return false; // 顺序表已满}if(pos < 1 || pos > L->length + 1){return false; // 位置不合法}for(int i = L->length; i >= pos; i--){L->data[i] = L->data[i-1]; // 向后移动元素 }L->data[pos-1] = elem;L->length++;return true;}```(3)删除顺序表中的元素```cbool Delete(SeqList *L, int pos){if(pos < 1 || pos > L->length){return false; // 位置不合法}for(int i = pos; i < L->length; i++){L->data[i-1] = L->data[i]; // 向前移动元素 }L->length--;return true;}```(4)查找顺序表中的元素```cint Search(SeqList L, int elem){for(int i = 0; i < L.length; i++){if(L.data[i] == elem){return i + 1; // 找到元素,返回位置 }}return -1; // 未找到元素}```2. 顺序表习题解答(1)逆置顺序表```cvoid Reverse(SeqList *L){for(int i = 0; i < L->length / 2; i++){int temp = L->data[i];L->data[i] = L->data[L->length - 1 - i]; L->data[L->length - 1 - i] = temp;}}```(2)顺序表元素去重```cvoid RemoveDuplicates(SeqList *L){for(int i = 0; i < L->length; i++){for(int j = i + 1; j < L->length; j++){if(L->data[i] == L->data[j]){Delete(L, j + 1);j--;}}}}```三、链表1. 单链表单链表是一种常见的链式存储结构,每个节点包含数据和指向下一个节点的指针。

数据结构(C语言版本)课后练习答案的完整版本.doc

数据结构(C语言版本)课后练习答案的完整版本.doc

数据结构(C语言版本)课后练习答案的完整版本第一章引言5。

选择题:CCBDCA 6。

尝试分析以下程序段的时间复杂性。

(1)o(1)(2)o(m * n)(3)o(N2)(4)o(log3n)(5)因为x已执行n-1n-2.1=n (n-1)/2,执行时间为O(n2)(6)O()第2章线性表1。

多项选择babadbcbdcddac 2。

算法设计问题(6)设计一种算法,通过一次遍历来确定单个链表中具有最大值的节点。

元素类型最大值(链表L ){如果(下一个==空)返回空;pmax=1-下一个;//假设第一个节点中的数据具有最大值p=L-下一个-下一个;同时(p!=NULL ){//如果在下一个节点处存在if(p-数据pmax-数据)pmax=p;p=p-下一个;}返回pmax-数据;(7)设计一种算法,通过遍历一次来反转链表中所有节点的链接方向,并且仍然使用原表的存储空间。

空逆(链表L) {//逆单个链表L p=L-头节点的下一个;下一个=空;而(p){ q=p-next;//q指向*p=l-next 的下一个p-next;l-next=p;//*p插入在头节点p=q之后;}}(10)已知长度n的线性表A采用顺序存储结构。

请编写一个时间复杂度为0(n)和空间复杂度为0(1)的算法,删除线性表中所有有值项的数据元素。

[主题分析]删除线性表中按顺序存储的元素通常涉及一系列元素的移动(删除第I个元素,并按顺序向前移动第I到第N个元素)。

本主题要求删除线性表中项目值为的所有数据元素,并且不要求元素之间的相对位置保持不变。

因此,可以考虑设置两个指针(i=1,j=n)从两端移到中间。

当遇到带有值项的数据元素时,右端元素将直接移动到带有值项的数据元素的位置。

虚删除(元素类型A[),整数n)A是一个有n个元素的一维数组。

此算法删除值为项的中的所有元素。

{ I=1;j=n。

∑设置数组的低端和高端指针(下标)。

同时(不精确;r=p;//让r 作为指针,而(q!=null){ if(q-data data)r=q;q:=q-next。

数据结构c语言版第三版习题解答

数据结构c语言版第三版习题解答

数据结构c语言版第三版习题解答数据结构 C 语言版第三版习题解答在学习计算机科学与技术的过程中,数据结构是一门非常重要的基础课程。

而《数据结构C 语言版第三版》更是众多教材中的经典之作。

其中的习题对于我们理解和掌握数据结构的概念、原理以及算法实现起着至关重要的作用。

接下来,我将为大家详细解答这本书中的一些典型习题。

首先,让我们来看一道关于线性表的习题。

题目是这样的:设计一个算法,从一个有序的线性表中删除所有其值重复的元素,使表中所有元素的值均不同。

对于这道题,我们可以采用双指针的方法来解决。

定义两个指针 p和 q,p 指向线性表的开头,q 从 p 的下一个位置开始。

当 q 所指向的元素与 p 所指向的元素相同时,我们就将 q 所指向的元素删除,并将 q 向后移动一位。

当 q 所指向的元素与 p 所指向的元素不同时,我们将 p 向后移动一位,并将 q 所指向的元素赋值给 p 所指向的位置,然后再将 q 向后移动一位。

当 q 超出线性表的范围时,算法结束。

下面是用 C 语言实现的代码:```cvoid removeDuplicates(int arr, int n) {int p = 0, q = 1;while (q < n) {if (arrp == arrq) {for (int i = q; i < n 1; i++){arri = arri + 1;}(n);} else {p++;arrp = arrq;}q++;}}```再来看一道关于栈的习题。

题目是:利用栈实现将一个十进制数转换为八进制数。

我们知道,将十进制数转换为八进制数可以通过不断除以 8 取余数的方法来实现。

而栈的特点是后进先出,正好适合存储这些余数。

以下是 C 语言实现的代码:```cinclude <stdioh>include <stdlibh>define MAX_SIZE 100typedef struct {int top;int dataMAX_SIZE;} Stack;//初始化栈void initStack(Stack s) {s>top =-1;}//判断栈是否为空int isEmpty(Stack s) {return s>top ==-1;}//判断栈是否已满int isFull(Stack s) {return s>top == MAX_SIZE 1;}//入栈操作void push(Stack s, int element) {if (isFull(s)){printf("Stack Overflow!\n");return;}s>data++s>top = element;}//出栈操作int pop(Stack s) {if (isEmpty(s)){printf("Stack Underflow!\n");return -1;}return s>datas>top;}//将十进制转换为八进制void decimalToOctal(int decimal) {Stack s;initStack(&s);while (decimal!= 0) {push(&s, decimal % 8);decimal /= 8;}while (!isEmpty(&s)){printf("%d", pop(&s));}printf("\n");}int main(){int decimal;printf("请输入一个十进制数: ");scanf("%d",&decimal);printf("转换后的八进制数为: ");decimalToOctal(decimal);return 0;}```接下来是一道关于队列的习题。

数据结构(C语言版)习题参考答案

数据结构(C语言版)习题参考答案

数据结构(C语言版)习题参考答案数据结构(C语言版)习题参考答案1. 数据结构简介数据结构是计算机科学中重要的概念之一,它关注如何组织和存储数据,以便有效地进行访问和操作。

C语言是一种广泛应用于数据结构实现的编程语言。

本文将提供一些常见数据结构习题的参考答案,帮助读者理解和掌握数据结构的基本概念与实现。

2. 数组数组是一种线性结构,存储具有相同数据类型的元素。

以下是一些数组习题的参考答案:2.1 统计数组中某个元素出现的次数```int countOccurrences(int arr[], int n, int x) {int count = 0;for (int i = 0; i < n; i++) {if (arr[i] == x) {count++;}}return count;}```2.2 查找数组中的最大值和最小值```void findMinMax(int arr[], int n, int* min, int* max) { *min = arr[0];*max = arr[0];for (int i = 1; i < n; i++) {if (arr[i] < *min) {*min = arr[i];}if (arr[i] > *max) {*max = arr[i];}}}```3. 链表链表是一种动态数据结构,每个节点包含数据和指向下一个节点的指针。

以下是一些链表习题的参考答案:3.1 反转链表```Node* reverseLinkedList(Node* head) {Node* prev = NULL;Node* curr = head;while (curr != NULL) {Node* next = curr->next;curr->next = prev;prev = curr;curr = next;}return prev;}```3.2 合并两个有序链表```Node* mergeLists(Node* list1, Node* list2) {if (list1 == NULL) {return list2;}if (list2 == NULL) {return list1;}if (list1->data < list2->data) {list1->next = mergeLists(list1->next, list2);return list1;} else {list2->next = mergeLists(list1, list2->next);return list2;}}```4. 栈和队列栈和队列是两种重要的线性数据结构,栈支持后进先出(LIFO),队列支持先进先出(FIFO)。

数据结构(C语言版)课后习题答案

数据结构(C语言版)课后习题答案

第1章绪论1.简述下列概念:数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、抽象数据类型。

答案:数据:是客观事物的符号表示,指所有能输入到计算机中并被计算机程序处理的符号的总称。

如数学计算中用到的整数和实数,文本编辑所用到的字符串,多媒体程序处理的图形、图像、声音、动画等通过特殊编码定义后的数据。

数据元素:是数据的基本单位,在计算机中通常作为一个整体进行考虑和处理。

在有些情况下,数据元素也称为元素、结点、记录等。

数据元素用于完整地描述一个对象,如一个学生记录,树中棋盘的一个格局(状态)、图中的一个顶点等。

数据项:是组成数据元素的、有独立含义的、不可分割的最小单位。

例如,学生基本信息表中的学号、姓名、性别等都是数据项。

数据对象:是性质相同的数据元素的集合,是数据的一个子集。

例如:整数数据对象是集合N={0,±1,±2,…},字母字符数据对象是集合C={‘A’,‘B’,…,‘Z’,‘a’,‘b’,…,‘z’},学生基本信息表也可是一个数据对象。

数据结构:是相互之间存在一种或多种特定关系的数据元素的集合。

换句话说,数据结构是带“结构”的数据元素的集合,“结构”就是指数据元素之间存在的关系。

逻辑结构:从逻辑关系上描述数据,它与数据的存储无关,是独立于计算机的。

因此,数据的逻辑结构可以看作是从具体问题抽象出来的数学模型。

存储结构:数据对象在计算机中的存储表示,也称为物理结构。

抽象数据类型:由用户定义的,表示应用问题的数学模型,以及定义在这个模型上的一组操作的总称。

具体包括三部分:数据对象、数据对象上关系的集合和对数据对象的基本操作的集合。

2.试举一个数据结构的例子,叙述其逻辑结构和存储结构两方面的含义和相互关系。

答案:例如有一张学生基本信息表,包括学生的学号、姓名、性别、籍贯、专业等。

每个学生基本信息记录对应一个数据元素,学生记录按顺序号排列,形成了学生基本信息记录的线性序列。

数据结构(C语言版)第三四章习题答案解析

数据结构(C语言版)第三四章习题答案解析

第3章栈和队列习题1.选择题(1)若让元素1,2,3,4,5依次进栈,则出栈次序不可能出现在()种情况。

A.5,4,3,2,1 B.2,1,5,4,3 C.4,3,1,2,5 D.2,3,5,4,1(2)若已知一个栈的入栈序列是1,2,3,…,n,其输出序列为p1,p2,p3,…,pn,若p1=n,则pi为()。

A.i B.n-i C.n-i+1 D.不确定(3)数组Q[n]用来表示一个循环队列,f为当前队列头元素的前一位置,r为队尾元素的位置,假定队列中元素的个数小于n,计算队列中元素个数的公式为()。

A.r-f B.(n+f-r)%n C.n+r-f D.(n+r-f)%n (4)链式栈结点为:(data,link),top指向栈顶.若想摘除栈顶结点,并将删除结点的值保存到x中,则应执行操作()。

A.x=top->data;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大于等于0if(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的容量至少应该是()。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第3章栈和队列一、基础知识题3.1有五个数依次进栈:1,2,3,4,5。

在各种出栈的序列中,以3,4先出的序列有哪几个。

(3在4之前出栈)。

【解答】34215 ,34251, 345213.2铁路进行列车调度时,常把站台设计成栈式结构,若进站的六辆列车顺序为:1,2,3,4,5,6,那么是否能够得到435612, 325641, 154623和135426的出站序列,如果不能,说明为什么不能;如果能,说明如何得到(即写出"进栈"或"出栈"的序列)。

【解答】输入序列为123456,不能得出435612和154623。

不能得到435612的理由是,输出序列最后两元素是12,前面4个元素(4356)得到后,栈中元素剩12,且2在栈顶,不可能让栈底元素1在栈顶元素2之前出栈。

不能得到154623的理由类似,当栈中元素只剩23,且3在栈顶,2不可能先于3出栈。

得到325641的过程如下:1 2 3顺序入栈,32出栈,得到部分输出序列32;然后45入栈,5出栈,部分输出序列变为325;接着6入栈并退栈,部分输出序列变为3256;最后41退栈,得最终结果325641。

得到135426的过程如下:1入栈并出栈,得到部分输出序列1;然后2和3入栈,3出栈,部分输出序列变为13;接着4和5入栈,5,4和2依次出栈,部分输出序列变为13542;最后6入栈并退栈,得最终结果135426。

3.3若用一个大小为6的数组来实现循环队列,且当前rear和front的值分别为0和3,当从队列中删除一个元素,再加入两个元素后,rear和front的值分别为多少?【解答】2和 43.4设栈S和队列Q的初始状态为空,元素e1,e2,e3,e4,e5和e6依次通过栈S,一个元素出栈后即进队列Q,若6个元素出队的序列是e3,e5,e4,e6,e2,e1,则栈S的容量至少应该是多少?【解答】 43.5循环队列的优点是什么,如何判断“空”和“满”。

【解答】循环队列解决了常规用0--m-1的数组表示队列时出现的“假溢出”(即队列未满但不能入队)。

在循环队列中我们仍用队头指针等于队尾指针表示队空,而用牺牲一个单元的办法表示队满,即当队尾指针加1(求模)等于队头指针时,表示队列满。

也有通过设标记以及用一个队头或队尾指针加上队中元素个数来区分队列的“空”和“满”的。

3.6设长度为n的链队列用单循环链表表示,若只设头指针,则入队和出队的时间如何?若只设尾指针呢?【解答】若只设头指针,则入队的时间为O(n),出队的时间为O(1)。

若只设尾指针,则入队和出队的时间均为O(1)。

3.7指出下面程序段的功能是什么?(1)void demo1(SeqStack S){int i,arr[64],n=0;while(!StackEmpty(S)) arr[n++]=Pop(S);for(i=0;i<n;i++) Push(S,arr[i]);}【解答】程序段的功能是实现了栈中元素的逆置。

(2)void demo2(SeqStack S,int m)∥设栈中元素类型为int型{int x;SeqStack T;StackInit(T);while(!StackEmpty(S))if((x=Pop(S)!=m) Push(T,x);while(!(StackEmpty(T)) {x=Pop(T); Push(S,x);}}【解答】程序段的功能是删除了栈中值为m的元素。

(3)void demo3(SeQueue Q,int m)∥设队列中元素类型为int型{int x;SeqStack S;StackInit(S);while(!QueueEmpty(Q)){x=QueueOut(Q); Push(S,x);}while(!StackEmpty(S)){x=Pop(s); QueueIn(Q,x);}}【解答】程序段的功能是实现了队列中元素的逆置。

3.8试将下列递推过程改写为递归过程。

void ditui(int n){i=n;while(i>1) printf(i--);}【解答】void digui(int n){if(n>1){printf(n);digui(n-1);}}3.9写出下列中缀表达式的后缀表达式:(1)A*B*C (2)(A+B)*C-D (3)A*B+C/(D-E) (4)(A+B)*D+E/(F+A*D)+C 【解答】(1)ABC**(2)AB+C*D-(3)AB*CDE-/+(4)AB+D*EFAD*+/+C+3.10选择题:循环队列存储在数组A[0..m]中,则入队时的操作为( )。

A. rear=rear+1B. rear=(rear+1) % (m-1)C. rear=(rear+1) % mD. rear=(rear+1) % (m+1)【解答】D3.11 选择题:4个园盘的Hahoi塔,总的移动次数为( )。

A.7B. 8C.15D.16【解答】C3.12选择题:允许对队列进行的操作有( )。

A. 对队列中的元素排序B. 取出最近进队的元素C. 在队头元素之前插入元素D. 删除队头元素【解答】D二、算法设计题3.13 利用栈的基本操作,编写求栈中元素个数的算法。

【题目分析】将栈值元素出栈,出栈时计数,直至栈空。

【算法】int StackLength(Stack S){//求栈中元素个数int n=0;while(!StackEmpty(S){n++; Pop(S);}return n;}算法讨论:若要求统计完元素个数后,不能破坏原来栈,则在计数时,将原栈导入另一临时栈,计数完毕,再将临时栈倒入原栈中。

int StackLength(Stack S){//求栈中元素个数int n=0;Stack T;StackInit(T); //初始化临时栈Twhile(!StackEmpty(S){n++; Push(T,Pop(S));}while(!StackEmpty(T){Push(S,Pop(T));}return n;}3.14 双向栈S是在一个数组空间V[m]实现的两个栈,栈底分别处于数组空间的两端。

试为此双向栈设计栈初始化Init(S)、入栈Push(S,i,x)、出栈Pop(S,i)算法,其中i为0或1,用以指示栈号。

[题目分析]两栈共享向量空间,将两栈栈底设在向量两端,初始时,s1栈顶指针为-1,s2栈顶为m。

两栈顶指针相邻时为栈满。

两栈顶相向、迎面增长,栈顶指针指向栈顶元素。

#define ElemType int ∥假设元素类型为整型typedef struct{ElemType V[m]; ∥栈空间int top[2]; ∥top为两个栈顶指针}stk;stk S; ∥S是如上定义的结构类型变量,为全局变量(1)栈初始化int Init(){S.top[0]=-1;S.top[1]=m;return 1; //初始化成功}(2)入栈操作:int push(stk S ,int i,int x)∥i为栈号,i=0表示左栈,i=1为右栈,x是入栈元素。

入栈成功返回1,否则返回0{if(i<0||i>1){printf(“栈号输入不对\n”);exit(0);}if(S.top[1]-S.top[0]==1) {printf(“栈已满\n”);return(0);}switch(i){case 0: S.V[++S.top[0]]=x; return(1); break;case 1: S.V[--S.top[1]]=x; return(1);}}∥push(3)退栈操作ElemType pop(stk S,int i)∥退栈。

i代表栈号,i=0时为左栈,i=1时为右栈。

退栈成功返回退栈元素∥否则返回-1{if(i<0 || i>1){printf(“栈号输入错误\n”);exit(0);}switch(i){case0: if(S.top[0]==-1) {printf(“栈空\n”);return(-1);}else return(S.V[S.top[0]--]);case 1: if(S.top[1]==m {printf(“栈空\n”); return(-1);}else return(S.V[S.top[1]++]);}∥switch }∥算法结束(4)判断栈空int Empty();{return (S.top[0]==-1 && S.top[1]==m);}[算法讨论]请注意算法中两栈入栈和退栈时的栈顶指针的计算。

s1(左栈)是通常意义下的栈,而s2(右栈)入栈操作时,其栈顶指针左移(减1),退栈时,栈顶指针右移(加1)。

3.15设以数组Q[m]存放循环队列中的元素,同时设置一个标志tag,以tag=0和tag=1来区别在队头指针(front)和队尾指针(rear)相等时,队列状态为“空”还是“不空”。

试编写相应的入队(QueueIn)和出队(QueueOut)算法。

(1)初始化SeQueue QueueInit(SeQueue Q){//初始化队列Q.front=Q.rear=0; Q.tag=0;return Q;}(2)入队SeQueue QueueIn(SeQueue Q,int e){//入队列if((Q.tag==1) && (Q.rear==Q.front)) printf("队列已满\n");else {Q.rear=(Q.rear+1) % m;Q.data[Q.rear]=e;if(Q.tag==0) Q.tag=1; //队列已不空}return Q;}(3)出队ElemType QueueOut(SeQueue Q){//出队列if(Q.tag==0) printf("队列为空\n");else{Q.front=(Q.front+1) % m;e=Q.data[Q.front];if(Q.front==Q.rear) Q.tag=0; //空队列}return(e);}3.16假设用变量rear和length分别指示循环队列中队尾元素的位置和含元素的个数。

试给出此循环队列的定义,并写出相应的入队(QueueIn)和出队(QueueOut)算法。

【算法设计】(1)循环队列的定义typedef struct{ElemType Q[m]; ∥循环队列占m个存储单元int rear,length; ∥ rear指向队尾元素,length为元素个数}SeQueue;(2) 初始化SeQueue QueueInit (SeQueue cq)∥cq为循环队列,本算法进行队列初始化{ cq.rear=0; cq.length=0; return cq;}(3) 入队SeQueue QueueIn(SeQueue cq,ElemType x)∥cq是以如上定义的循环队列,本算法将元素x入队{if(cq.length==m) return(0); ∥队满else {cq.rear=(cq.rear+1) % m; ∥计算插入元素位置cq.Q[cq.rear]=x; ∥将元素x入队列cq.length++; ∥修改队列长度}return (cq);}(4)出队ElemType QueueOut(SeQueue cq)∥ cq是以如上定义的循环队列,本算法是出队算法,且返回出队元素{if(cq.length==0) return(0); ∥队空else { int front=(cq.rear-cq.length + 1) % m;∥出队元素位置cq.length--; ∥修改队列长度 return (cq.Q[front]); ∥返回对头元素}}3.17已知Ackerman函数定义如下:Akm(m,n)=试写出递归和非递归算法。

相关文档
最新文档