数据结构及应用算法教程习题第三章 排序

合集下载

数据结构第三章习题答案解析

数据结构第三章习题答案解析

第三章习题1.按图3.1(b)所示铁道(两侧铁道均为单向行驶道)进行车厢调度,回答:⑴如进站的车厢序列为123,则可能得到的出站车厢序列是什么?⑵如进站的车厢序列为123456,能否得到435612和135426的出站序列,并说明原因。

(即写出以“S”表示进栈、以“X”表示出栈的栈操作序列)。

2.设队列中有A、B、C、D、E这5个元素,其中队首元素为A。

如果对这个队列重复执行下列4步操作:(1)输出队首元素;(2)把队首元素值插入到队尾;(3)删除队首元素;(4)再次删除队首元素。

直到队列成为空队列为止,得到输出序列:(1)A、C、E、C、C (2) A、C、E(3) A、C、E、C、C、C (4) A、C、E、C3.给出栈的两种存储结构形式名称,在这两种栈的存储结构中如何判别栈空与栈满?4.按照四则运算加、减、乘、除和幂运算(↑)优先关系的惯例,画出对下列算术表达式求值时操作数栈和运算符栈的变化过程:A-B*C/D+E↑F5.试写一个算法,判断依次读入的一个以@为结束符的字母序列,是否为形如‘序列1& 序列2’模式的字符序列。

其中序列1和序列2中都不含字符’&’,且序列2是序列1的逆序列。

例如,‘a+b&b+a’是属该模式的字符序列,而‘1+3&3-1’则不是。

6.假设表达式由单字母变量和双目四则运算算符构成。

试写一个算法,将一个通常书写形式且书写正确的表达式转换为逆波兰式。

7.假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾元素结点(注意不设头指针),试编写相应的队列初始化、入队列和出队列的算法。

8.要求循环队列不损失一个空间全部都能得到利用, 设置一个标志域tag , 以tag为0或1来区分头尾指针相同时的队列状态的空与满,请编写与此结构相应的入队与出队算法。

9.简述以下算法的功能(其中栈和队列的元素类型均为int):(1)void proc_1(Stack S){ int i, n, A[255];n=0;while(!EmptyStack(S)){n++; Pop(&S, &A[n]);}for(i=1; i<=n; i++)Push(&S, A[i]);}(2)void proc_2(Stack S, int e) { Stack T; int d;InitStack(&T);while(!EmptyStack(S)){ Pop(&S, &d);if (d!=e) Push( &T, d);}while(!EmptyStack(T)){ Pop(&T, &d);Push( &S, d);}}(3)void proc_3(Queue *Q){ Stack S; int d;InitStack(&S);while(!EmptyQueue(*Q)){DeleteQueue(Q, &d);Push( &S, d);}while(!EmptyStack(S)){ Pop(&S, &d);EnterQueue(Q,d)}}实习题1.回文判断。

数据结构 习题 第三章 栈和队列 答案

数据结构 习题 第三章 栈和队列 答案

第三章栈和队列部分答案解释如下。

1、尾递归的消除就不需用栈2、这个数是前序序列为1,2,3,…,n,所能得到的不相似的二叉树的数目。

三、填空题1、操作受限(或限定仅在表尾进行插入和删除操作)后进先出2、栈3、3 1 24、23 100CH5、0 n+1 top[1]+1=top[2]6、两栈顶指针值相减的绝对值为1(或两栈顶指针相邻)。

7、(1)满 (2)空 (3)n (4)栈底 (5)两栈顶指针相邻(即值之差的绝对值为1)8、链式存储结构 9、S×SS×S×× 10、data[++top]=x;11、23.12.3*2-4/34.5*7/++108.9/+(注:表达式中的点(.)表示将数隔开,如23.12.3是三个数)12、假溢出时大量移动数据元素。

13、(M+1) MOD N (M+1)% N; 14、队列 15、先进先出 16、先进先出 17、s=(LinkedList)malloc(sizeof(LNode)); s->data=x;s->next=r->next;r->next=s;r=s;18、牺牲一个存储单元设标记19、(TAIL+1)MOD M=FRONT (数组下标0到M-1,若一定使用1到M,则取模为0者,值改取M20、sq.front=(sq.front+1)%(M+1);return(sq.data(sq.front));(sq.rear+1)%(M+1)==sq.front;21、栈 22、(rear-front+m)% m; 23、(R-P+N)% N;24、(1)a[i]或a[1] (2)a[i] (3)pop(s)或s[1];25、(1)PUSH(OPTR,w)(2)POP(OPTR)(3)PUSH(OPND,operate(a,theta,b))26、(1)T>0(2)i<n(3)T>0(4)top<n(5)top+1(6)true(7)i-1(8)top-1(9)T+w[i](10)false四、应用题1、栈是只准在一端进行插入和删除操作的线性表,允许插入和删除的一端叫栈顶,另一端叫栈底。

数据结构第三章习题答案解析

数据结构第三章习题答案解析

第三章习题1.按图3.1(b)所示铁道(两侧铁道均为单向行驶道)进行车厢调度,回答:⑴如进站的车厢序列为123,则可能得到的出站车厢序列是什么?⑵如进站的车厢序列为123456,能否得到435612和135426的出站序列,并说明原因。

(即写出以“S”表示进栈、以“X”表示出栈的栈操作序列)。

2.设队列中有A、B、C、D、E这5个元素,其中队首元素为A。

如果对这个队列重复执行下列4步操作:(1)输出队首元素;(2)把队首元素值插入到队尾;(3)删除队首元素;(4)再次删除队首元素。

直到队列成为空队列为止,得到输出序列:(1)A、C、E、C、C (2) A、C、E(3) A、C、E、C、C、C (4) A、C、E、C3.给出栈的两种存储结构形式名称,在这两种栈的存储结构中如何判别栈空与栈满?4.按照四则运算加、减、乘、除和幂运算(↑)优先关系的惯例,画出对下列算术表达式求值时操作数栈和运算符栈的变化过程:A-B*C/D+E↑F5.试写一个算法,判断依次读入的一个以@为结束符的字母序列,是否为形如‘序列1& 序列2’模式的字符序列。

其中序列1和序列2中都不含字符’&’,且序列2是序列1的逆序列。

例如,‘a+b&b+a’是属该模式的字符序列,而‘1+3&3-1’则不是。

6.假设表达式由单字母变量和双目四则运算算符构成。

试写一个算法,将一个通常书写形式且书写正确的表达式转换为逆波兰式。

7.假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾元素结点(注意不设头指针),试编写相应的队列初始化、入队列和出队列的算法。

8.要求循环队列不损失一个空间全部都能得到利用, 设置一个标志域tag , 以tag为0或1来区分头尾指针相同时的队列状态的空与满,请编写与此结构相应的入队与出队算法。

9.简述以下算法的功能(其中栈和队列的元素类型均为int):(1)void proc_1(Stack S){ int i, n, A[255];n=0;while(!EmptyStack(S)){n++; Pop(&S, &A[n]);}for(i=1; i<=n; i++)Push(&S, A[i]);}(2)void proc_2(Stack S, int e){ Stack T; int d;InitStack(&T);while(!EmptyStack(S)){ Pop(&S, &d);if (d!=e) Push( &T, d);}while(!EmptyStack(T)){ Pop(&T, &d);Push( &S, d);}}(3)void proc_3(Queue *Q){ Stack S; int d;InitStack(&S);while(!EmptyQueue(*Q)){DeleteQueue(Q, &d);Push( &S, d);}while(!EmptyStack(S)){ Pop(&S, &d);EnterQueue(Q,d)}}实习题1.回文判断。

数据结构第三章的习题答案

数据结构第三章的习题答案

数据结构第三章的习题答案数据结构第三章的习题答案在学习数据结构的过程中,习题是巩固知识和提高能力的重要方式。

第三章的习题主要涉及线性表、栈和队列的实现和操作。

本文将对这些习题进行解答,并给出详细的步骤和思路。

1. 第一题要求实现一个线性表的插入操作。

线性表是一种常用的数据结构,它的特点是元素之间存在一对一的关系。

要实现插入操作,首先需要定义线性表的数据结构,可以使用数组或链表来实现。

然后,根据插入位置,将插入位置之后的元素依次后移,为要插入的元素腾出空间。

最后,将要插入的元素放入插入位置。

2. 第二题要求实现一个栈的压栈和出栈操作。

栈是一种后进先出(LIFO)的数据结构,可以使用数组或链表来实现。

压栈操作就是将元素放入栈顶,出栈操作就是将栈顶元素取出并删除。

要实现这两个操作,可以使用一个指针来指示栈顶位置,每次压栈时将指针加一,出栈时将指针减一。

需要注意的是,栈满时不能再进行压栈操作,栈空时不能进行出栈操作。

3. 第三题要求实现一个队列的入队和出队操作。

队列是一种先进先出(FIFO)的数据结构,同样可以使用数组或链表来实现。

入队操作就是将元素放入队尾,出队操作就是将队头元素取出并删除。

与栈不同的是,队列需要维护队头和队尾两个指针。

每次入队时将元素放入队尾,并将队尾指针后移一位;出队时将队头元素取出,并将队头指针后移一位。

需要注意的是,队列满时不能再进行入队操作,队列空时不能进行出队操作。

4. 第四题要求实现一个栈的括号匹配算法。

括号匹配是一种常见的应用场景,例如编程语言中的括号匹配。

要实现这个算法,可以使用栈来辅助。

遍历字符串中的每个字符,如果是左括号,则将其压入栈中;如果是右括号,则将栈顶元素取出并判断是否与右括号匹配。

如果匹配,则继续遍历下一个字符;如果不匹配,则说明括号不匹配,返回错误。

最后,如果栈为空,则说明括号匹配成功;如果栈不为空,则说明括号不匹配,返回错误。

5. 第五题要求使用栈实现一个逆波兰表达式的计算器。

《数据结构及其应用》笔记含答案 第三章_栈和队列

《数据结构及其应用》笔记含答案 第三章_栈和队列

第3章栈和队列一、填空题1、栈是限定仅在表尾进行插入或删除操作的线性表。

2、栈的修改是按照后进先出的原则进行的。

3、队是一种先进先出的线性表。

4、把队列头尾相接的顺序存储结构称为循环队列。

5、队列也是一种操作受限的线性表,允许插入的一端叫做__队尾___,允许删除的一端叫做__队头__。

二、判断题1、栈和队列的存储,既可以采用顺序存储结构,又可以采用链式存储结构。

(√)2、任何一个递归过程都可以转换成非递归过程。

(√)3、若输入序列为1,2,3,4,5,6,则通过一个栈可以输出序列3,2,5,6,4,1。

(√)4、通常使用队列来处理函数的调用。

(╳)5、循环队列通常用指针来实现队列的头尾相接。

(╳)三、单项选择题1、若让元素1,2,3,4,5依次进栈,则出栈次序不可能出现在(C)种情况。

A.5,4,3,2,1 B.2,1,5,4,3 C.4,3,1,2,5 D.2,3,5,4,1解释:栈是后进先出的线性表,不难发现C选项中元素1比元素2先出栈,违背了栈的后进先出原则,所以不可能出现C选项所示的情况。

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

A.i B.n-i C.n-i+1 D.不确定解释:栈是后进先出的线性表,一个栈的入栈序列是1,2,3,…,n,而输出序列的第一个元素为n,说明1,2,3,…,n一次性全部进栈,再进行输出,所以p1=n,p2=n-1,…,pi=n-i+1。

3、数组Q[n]用来表示一个循环队列,f为当前队列头元素的前一位置,r为队尾元素的位置,假定队列中元素的个数小于n,计算队列中元素个数的公式为(D)。

A.r-f B.(n+f-r)%n C.n+r-f D.(n+r-f)%n解释:对于非循环队列,尾指针和头指针的差值便是队列的长度,而对于循环队列,差值可能为负数,所以需要将差值加上MAXSIZE(本题为n),然后与MAXSIZE(本题为n)求余,即(n+r-f)%n。

数据结构第三章习题

数据结构第三章习题

数据结构第三章习题本文共分为三部分,分别针对数据结构第三章中的不同习题进行解答。

第一部分,解答关于树和二叉树的习题。

1.对于给定的有“n(n>0)”个结点的树,边数应为“n-1”条。

解析:树是一种无环连通无向图,因此任意n个结点的树有n-1条边。

2.往2(2≤n≤64)叉树的每个结点上添加一个数据元素,设计一个数据结构,实现迅速求该2叉树中所有结点的数据元素之和。

解析:可以使用先序遍历算法来完成,先序遍历树的根节点,然后递归遍历左子树和右子树,将每个结点的数据元素加和。

3.设计一个算法,判定给定的二叉树是否是完全二叉树。

解析:可以使用层次遍历算法来判定。

如果一棵树是完全二叉树,那么层次遍历结果中,如果一些结点有右孩子,那么该结点之后的所有结点都必须有孩子;如果一些结点没有右孩子,则该结点之后的所有结点都不能有孩子。

4.设有一棵完全二叉树,编写算法,生成一棵采用二叉链表存储结构的二叉树。

解析:可以使用层次遍历算法来构建树。

从根节点开始,依次按层次遍历的顺序遍历所有结点,依次将结点和它的孩子结点用链表链接起来。

第二部分,解答关于图的习题。

1.利用邻接表存储图,写出一个算法,判断两个节点之间是否存在路径。

解析:可以使用深度优先算法或广度优先算法来判断两个节点之间是否存在路径。

首先从起始节点开始,遍历其邻接节点,递归或使用队列来保存需要遍历的节点,直到遍历到目标节点或遍历完所有的节点。

2.利用邻接表存储图,写出一个算法,求图的连通分量个数。

解析:可以使用深度优先算法或广度优先算法来求图的连通分量个数。

首先从起始节点开始,遍历其邻接节点,标记遍历过的节点,直到遍历完所有的节点。

每次从一个未标记的节点开始进行遍历,当所有的节点都被遍历过后,即可得到图的连通分量个数。

3.利用邻接表存储图,写出一个算法,判断给定的图是否为无向图。

解析:可以遍历所有的边,对于每一条边(u,v),如果(u,v)存在,则判断(v,u)是否存在,如果都存在,则图为无向图,否则为有向图。

严蔚敏《数据结构(c语言版)习题集》算法设计题第三章参考答案

严蔚敏《数据结构(c语言版)习题集》算法设计题第三章参考答案

严蔚敏《数据结构(c语言版)习题集》算法设计题第三章参考答案第三章栈与队列typedef struct{Elemtype *base[ ];Elemtype *top[ ];}BDStacktype; //双向栈类型Status Init_Stack(BDStacktype &s int m)//初始化一个大小为m 的双向栈s{s base[ ]=(Elemtype*)malloc(sizeof(Elemtype));s base[ ]=s base[ ]+m;s top[ ]=s base[ ];s top[ ]=s base[ ];return OK;}//Init_StackStatus push(BDStacktype &s int i Elemtype x)//x入栈 i= 表示低端栈 i= 表示高端栈{if(s top[ ]>s top[ ]) return OVERFLOW; //注意此时的栈满条件if(i== ) *s top[ ]++=x;else if(i== ) *s top[ ] =x;else return ERROR;return OK;}//pushStatus pop(BDStacktype &s int i Elemtype &x)//x出栈 i= 表示低端栈 i= 表示高端栈{if(i== ){if(s top[ ]==s base[ ]) return OVERFLOW;x=* s top[ ];}else if(i== ){if(s top[ ]==s base[ ]) return OVERFLOW;x=*++s top[ ];}else return ERROR;return OK;}//popvoid Train_arrange(char *train)//这里用字符串train表示火车 H 表示硬席 S 表示软席{p=train;q=train;InitStack(s);while(*p){if(*p== H ) push(s *p); //把 H 存入栈中else *(q++)=*p; //把 S 调到前部p++;}while(!StackEmpty(s)){pop(s c);*(q++)=c; //把 H 接在后部}}//Train_arrangeint IsReverse()//判断输入的字符串中 & 前和 & 后部分是否为逆串是则返回否则返回{InitStack(s);while((e=getchar())!= & )push(s e);while((e=getchar())!= @ ){if(StackEmpty(s)) return ;pop(s c);if(e!=c) return ;}if(!StackEmpty(s)) return ;return ;}//IsReverseStatus Bracket_Test(char *str)//判别表达式中小括号是否匹配{count= ;for(p=str;*p;p++){if(*p== ( ) count++;else if(*p== ) ) count ;if (count< ) return ERROR;}if(count) return ERROR; //注意括号不匹配的两种情况return OK;}//Bracket_TestStatus AllBrackets_Test(char *str)//判别表达式中三种括号是否匹配{InitStack(s);for(p=str;*p;p++){if(*p== ( ||*p== [ ||*p== { ) push(s *p);else if(*p== ) ||*p== ] ||*p== } ){if(StackEmpty(s)) return ERROR;pop(s c);if(*p== ) &&c!= ( ) return ERROR;if(*p== ] &&c!= [ ) return ERROR;if(*p== } &&c!= { ) return ERROR; //必须与当前栈顶括号匹配}}//forif(!StackEmpty(s)) return ERROR;return OK;}//AllBrackets_Testtypedef struct {int x;int y;} coordinate;void Repaint_Color(int g[m][n] int i int j int color)//把点(i j)相邻区域的颜色置换为color{old=g[i][j];InitQueue(Q);EnQueue(Q {I j});while(!QueueEmpty(Q)){DeQueue(Q a);x=a x;y=a y;if(x> )if(g[x ][y]==old){g[x ][y]=color;EnQueue(Q {x y}); //修改左邻点的颜色}if(y> )if(g[x][y ]==old){g[x][y ]=color;EnQueue(Q {x y }); //修改上邻点的颜色}if(xif(g[x+1][y]==old){g[x+1][y]=color;EnQueue(Q,{x+1,y}); //修改右邻点的颜色}if(yif(g[x][y+1]==old){g[x][y+1]=color;EnQueue(Q,{x,y+1}); //修改下邻点的颜色}}//while}//Repaint_Color分析:本算法采用了类似于图的广度优先遍历的思想,用两个队列保存相邻同色点的横坐标和纵坐标.递归形式的算法该怎么写呢?3.21void NiBoLan(char *str,char *new)//把中缀表达式str转换成逆波兰式new{p=str;q=new; //为方便起见,设str的两端都加上了优先级最低的特殊符号InitStack(s); //s为运算符栈while(*p){if(*p是字母)) *q++=*p; //直接输出else{c=gettop(s);if(*p优先级比c高) push(s,*p);else{while(gettop(s)优先级不比*p低){pop(s,c);*(q++)=c;}//whilepush(s,*p); //运算符在栈内遵循越往栈顶优先级越高的原则}//else}//elsep++;}//while}//NiBoLan //参见编译原理教材3.22int GetValue_NiBoLan(char *str)//对逆波兰式求值{p=str;InitStack(s); //s为操作数栈while(*p){if(*p是数) push(s,*p);else{pop(s,a);pop(s,b);r=pute(b,*p,a); //假设pute为执行双目运算的过程push(s,r);}//elsep++;}//whilepop(s,r);return r;}//GetValue_NiBoLan3.23Status NiBoLan_to_BoLan(char *str,stringtype &new)//把逆波兰表达式str转换为波兰式new{p=str;Initstack(s); //s的元素为stringtype类型while(*p){if(*p为字母) push(s,*p);else{if(StackEmpty(s)) return ERROR;pop(s,a);if(StackEmpty(s)) return ERROR;pop(s,b);c=link(link(*p,b),a);push(s,c);}//elsep++;}//whilepop(s,new);if(!StackEmpty(s)) return ERROR;return OK;}//NiBoLan_to_BoLan分析:基本思想见书后注释.本题中暂不考虑串的具体操作的实现,而将其看作一种抽象数据类型stringtype,对其可以进行连接操作:c=link(a,b).3.24Status g(int m,int n,int &s)//求递归函数g的值s{if(m==0&&n>=0) s=0;else if(m>0&&n>=0) s=n+g(m-1,2*n);else return ERROR;return OK;}//g3.25Status F_recursive(int n,int &s)//递归算法{if(n<0) return ERROR;if(n==0) s=n+1;else{F_recurve(n/2,r);s=n*r;}return OK;}//F_recursiveStatus F_nonrecursive(int n,int s)//非递归算法{if(n<0) return ERROR;if(n==0) s=n+1;else{InitStack(s); //s的元素类型为struct {int a;int b;}while(n!=0){a=n;b=n/2;push(s,{a,b});n=b;}//whiles=1;while(!StackEmpty(s)){pop(s,t);s*=t.a;}//while}return OK;}//F_nonrecursive3.26float Sqrt_recursive(float A,float p,float e)//求平方根的递归算法{if(abs(p^2-A)<=e) return p;else return sqrt_recurve(A,(p+A/p)/2,e);}//Sqrt_recurve。

数据结构课后习题答案第三章

数据结构课后习题答案第三章

第三章栈和队列(参考答案)// 从数据结构角度看,栈和队列是操作受限的线性结构,其顺序存储结构// 和链式存储结构的定义与线性表相同,请参考教材,这里不再重复。

3.1 1 2 3 4 2 1 3 4 3 2 1 4 4 3 2 11 2 4 3 2 1 4 3 3 2 4 11 32 4 23 14 3 4 2 11 3 42 234 11 4 32 2 43 1设入栈序列元素数为n,则可能的出栈序列数为C2n n=(1/n+1)*(2n!/(n!)2)3.2 证明:由j<k和p j<p k说明p j在p k之前出栈,即在k未进栈之前p j已出栈,之后k进栈,然后p k出栈;由j<k和p j>p k说明p j在p k之后出栈,即p j被p k压在下面,后进先出。

由以上两条,不可能存在i<j<k使p j<p k<p i。

也就是说,若有1,2,3顺序入栈,不可能有3,1,2的出栈序列。

3.3 void sympthy(linklist *head, stack *s)//判断长为n的字符串是否中心对称{ int i=1; linklist *p=head->next;while (i<=n/2) // 前一半字符进栈{ push(s,p->data); p=p->next; }if (n % 2 !==0) p=p->next;// 奇数个结点时跳过中心结点while (p && p->data==pop(s)) p=p->next;if (p==null) printf(“链表中心对称”);else printf(“链表不是中心对称”);} // 算法结束3.4int match()//从键盘读入算术表达式,本算法判断圆括号是否正确配对(init s;//初始化栈sscanf(“%c”,&ch);while (ch!=’#’) //’#’是表达式输入结束符号switch (ch){ case ’(’: push(s,ch); break;case ’)’: if (empty(s)) {printf(“括号不配对”); exit(0);}pop(s);}if (!empty(s)) printf(“括号不配对”);else printf(“括号配对”);} // 算法结束3.5typedef struct // 两栈共享一向量空间{ ElemType v[m]; // 栈可用空间0—m-1int top[2] // 栈顶指针}twostack;int push(twostack *s,int i, ElemType x)// 两栈共享向量空间,i是0或1,表示两个栈,x是进栈元素,// 本算法是入栈操作{ if (abs(s->top[0] - s->top[1])==1) return(0);// 栈满else {switch (i){case 0: s->v[++(s->top)]=x; break;case 1: s->v[--(s->top)]=x; break;default: printf(“栈编号输入错误”); return(0);}return(1); // 入栈成功}} // 算法结束ElemType pop(twostack *s,int i)// 两栈共享向量空间,i是0或1,表示两个栈,本算法是退栈操作{ ElemType x;if (i!=0 && i!=1) return(0);// 栈编号错误else {switch (i){case 0: if(s->top[0]==-1) return(0);//栈空else x=s->v[s->top--];break;case 1: if(s->top[1]==m) return(0);//栈空else x=s->v[s->top++]; break;default: printf(“栈编号输入错误”);return(0);}return(x); // 退栈成功}} // 算法结束ElemType top (twostack *s,int i)// 两栈共享向量空间,i是0或1,表示两个栈,本算法是取栈顶元素操作{ ElemType x;switch (i){case 0: if(s->top[0]==-1) return(0);//栈空else x=s->v[s->top]; break;case 1: if(s->top[1]==m) return(0);//栈空else x=s->v[s->top]; break;default: printf(“栈编号输入错误”);return(0);}return(x); // 取栈顶元素成功} // 算法结束3.6void Ackerman(int m,int n)// Ackerman 函数的递归算法{ if (m==0) return(n+1);else if (m!=0 && n==0) return(Ackerman(m-1,1);else return(Ackerman(m-1,Ackerman(m,n-1))} // 算法结束3.7(1) linklist *init(linklist *q)// q是以带头结点的循环链表表示的队列的尾指针,本算法将队列置空{ q=(linklist *)malloc(sizeof(linklist));//申请空间,不判断空间溢出q->next=q;return (q);} // 算法结束(2) linklist *enqueue(linklist *q,ElemType x)// q是以带头结点的循环链表表示的队列的尾指针,本算法将元素x入队{ s=(linklist *)malloc(sizeof(linklist));//申请空间,不判断空间溢出s->next=q->next; // 将元素结点s入队列q->next=s;q=s; // 修改队尾指针return (q);} // 算法结束(3) linklist *delqueue(linklist *q)//q是以带头结点的循环链表表示的队列的尾指针,这是出队算法{ if (q==q->next) return (null); // 判断队列是否为空else {linklist *s=q->next->next; // s指向出队元素if (s==q) q=q->next; // 若队列中只一个元素,置空队列else q->next->next=s->next;// 修改队头元素指针free (s); // 释放出队结点}return (q);} // 算法结束。

数据结构习题答案第3章

数据结构习题答案第3章

选择题第3章线性表的链式存储(1)两个有序线性表分别具有n个元素与m个元素且n≤m,现将其归并成一个有序表,其最少的比较次数是( A )。

A.n B.m C.n− 1D.m + n(2)非空的循环单链表 head 的尾结点(由 p 所指向)满足( C )。

A.p->next==NULL B.p==NULL C.p->next==head D.p==head(3)在带头结点的单链表中查找x应选择的程序体是( C )。

A.node *p=head->next; while (p && p->info!=x) p=p->next;if (p->info==x) return p else return NULL;B.node *p=head; while (p&& p->info!=x) p=p->next; return p;C.node *p=head->next; while (p&&p->info!=x) p=p->next; return p;D.node *p=head; while (p->info!=x) p=p->next ; return p;(4)线性表若采用链式存储结构时,要求内存中可用存储单元的地址( D )。

A.必须是连续的C.一定是不连续的B.部分地址必须是连续的D.连续不连续都可以(5)在一个具有n个结点的有序单链表中插入一个新结点并保持单链表仍然有序的时间复杂度是( B )。

A.O(1) B.O(n)C.O(n2)D.O(n log2n)(6)用不带头结点的单链表存储队列时,其队头指针指向队头结点,其队尾指针指向队尾结点,则在进行删除操作时(D )。

A.仅修改队头指针C.队头、队尾指针都要修改B.仅修改队尾指针D.队头,队尾指针都可能要修改(7)若从键盘输入n个元素,则建立一个有序单向链表的时间复杂度为( B )。

数据结构与算法(C语言篇)第3章 习题答案[3页]

数据结构与算法(C语言篇)第3章 习题答案[3页]

习题答案1.填空题(1)栈(2)队列(3)后进先出(4)先进先出2.选择题(1)A (2)C (3)D (4)D、A (5)C (6)B3.思考题(1)栈是一种运算受限制的线性表,其只允许在表的一端进行插入和删除操作,俗称堆栈。

允许进行操作的一端称为“栈顶”,而另一个固定端称为“栈底”,栈中的数据在进行入栈和出栈时,遵循后进先出的原则。

队列同样是一种运算受限制的线性表,是限制在两端进行插入和删除操作的线性表。

允许进行插入操作的一端称为“队尾”,而允许进行删除操作的一端称为“队头”,队列中的数据在进行入队和出队时,遵循先进先出的原则。

4.编程题(1)//入栈//参数1为栈顶指针(头结点指针),参数2为插入的数据int linkstack_push(linkstack_t *s, datatype_t value){linkstack_t *temp;//使用malloc函数为新插入的结点申请内存空间temp = (linkstack_t *)malloc(sizeof(linkstack_t));//为新插入的结点赋值temp->data = value;//用头插法实现入栈temp->next = s->next;s->next = temp;return 0;}//判断栈是否为空int linkstack_empty(linkstack_t *s){return s->next == NULL ? 1 : 0; //判断下一个结点是否为空}//出栈datatype_t linkstack_pop(linkstack_t *s){linkstack_t *temp;datatype_t value;if(linkstack_empty(s)){printf("linkstack empty\n");return -1;}//头删法表示出栈,后入先出temp = s->next;s->next = temp->next;//保存出栈的数据value = temp->data;//释放出栈的结点的内存空间free(temp);temp = NULL;//返回出栈的数据return value;}(2)//入队//参数1为存放队列头尾结点指针的结构体地址,参数2为新入队的数据int linkqueue_enter(linkqueue_t *lq, datatype_t value){ linknode_t *temp;//使用malloc函数为头结点申请内存空间temp = (linknode_t *)malloc(sizeof(linknode_t));//采用尾插法的设计思想temp->data = value; //为新结点赋值temp->next = NULL; //将新结点的指针指向NULLlq->rear->next = temp; //入队,将新结点加入队列尾部lq->rear = temp; //移动rear指针,指向新加入的结点 return 0;}//判断队列是否为空int linkqueue_empty(linkqueue_t *lq){//当front与rear指向同一个结点时,判断队列为空return lq->front == lq->rear ? 1 : 0;}//出队//从头结点开始删除,包括头结点datatype_t linkqueue_out(linkqueue_t *lq){linknode_t *temp;datatype_t value;if(linkqueue_empty(lq)){printf("linkqueue empty\n");return -1;}temp = lq->front; //获取删除结点//移动front指针到下一个结点lq->front = lq->front->next;//获取下一个结点的数据value = lq->front->data;free(temp); //释放需要删除结点的内存空间 temp = NULL; //避免出现野指针//返回结点数据return value;}。

数据结构第三章参考答案

数据结构第三章参考答案

习题31.填空题(1)栈的进出原则是(___________),队列的进出原则是(___________)。

答案:后进先出(LIFO)先进先出(FIFO)(2)设32位计算机系统中,空栈S存储int型数据,栈顶指针为1024H。

经过操作序列push(1),push(2),pop,push(5),push(7),pop,push(6)之后,栈顶元素为(___________),栈底元素为(___________),栈的高度为(___________),输出序列是(___________),栈顶指针为(___________)H。

答案:6 1 3 2,7 1030(3)两栈共享存储空间,其数组大小为100,数组下标从0开始。

top1和top2分别为栈1和栈2的栈顶元素下标,则栈1为空的条件为(___________),栈2为空的条件为(___________),栈1或栈2满的条件为(___________)。

答案:top1==-1 top2==100 top1+1==top2(4)一个队列的入队顺序是1234,则队列的输出顺序是(___________)。

答案:1234(5)设循环队列数组大小为100,队头指针为front,队尾指针为rear;约定front指向队头元素的前一个位置,该位置永远不存放数据。

则入队操作时,修改rear=(___________),出队操作修改front=(___________),队空的判别条件为(___________),队满的判别条件为(___________)。

若front=20,rear=60,则队列长度为(___________),若front=60,rear=20,则队列长度为(___________)。

答案:(rear+1)%100 (front+1)%100 rear==front (rear+1)%100=front 40 60(6)朴素模式匹配算法中,每个串的起始下标均为1,变量i=100,j=10,分别表示主串和模式串当前比较的字符元素下标,若本次比较两字符不同,则i回溯为(___________),j 回溯为(___________)。

《数据结构》教材课后习题+答案

《数据结构》教材课后习题+答案

《数据结构》教材课后习题+答案数据结构第一章介绍数据结构是计算机科学中重要的概念,它涉及到组织和存储数据的方法和技术。

数据结构的选择对于算法的效率有着重要的影响。

本教材为读者提供了丰富的课后习题,以帮助读者巩固所学知识并提高解决问题的能力。

下面是一些选定的习题及其答案,供读者参考。

第二章线性表习题一:给定一个顺序表L,编写一个算法,实现将其中元素逆置的功能。

答案一:算法思路:1. 初始化两个指针i和j,分别指向线性表L的首尾两个元素2. 对于L中的每一个元素,通过交换i和j所指向的元素,将元素逆置3. 当i>=j时,停止逆置算法实现:```pythondef reverse_list(L):i, j = 0, len(L)-1while i < j:L[i], L[j] = L[j], L[i]i += 1j -= 1```习题二:给定两个线性表A和B,编写一个算法,将线性表B中的元素按顺序插入到线性表A中。

答案二:算法思路:1. 遍历线性表B中的每一个元素2. 将B中的元素依次插入到A的末尾算法实现:```pythondef merge_lists(A, B):for element in B:A.append(element)```第三章栈和队列习题一:编写一个算法,判断一个表达式中的括号是否匹配。

表达式中的括号包括小括号"()"、中括号"[]"和大括号"{}"。

答案一:算法思路:1. 遍历表达式中的每一个字符2. 当遇到左括号时,将其推入栈中3. 当遇到右括号时,判断栈顶元素是否与其匹配4. 当遇到其他字符时,继续遍历下一个字符5. 最后判断栈是否为空,若为空则表示括号匹配算法实现:```pythondef is_matching(expression):stack = []for char in expression:if char in "([{":stack.append(char)elif char in ")]}":if not stack:return Falseelif (char == ")" and stack[-1] == "(") or (char == "]" and stack[-1] == "[") or (char == "}" and stack[-1] == "{"):stack.pop()else:return Falsereturn not stack```习题二:利用两个栈实现一个队列。

数据结构排序操作题做法

数据结构排序操作题做法

数据结构排序操作题做法数据结构中的排序操作是一种常见而重要的算法,对于处理大规模数据和提高搜索效率至关重要。

排序算法涉及许多经典的问题和方法,下面将探讨排序算法的一般做法、几种常见的排序算法及其性能比较。

一般的排序做法选择合适的排序算法:根据具体需求和数据特性选择合适的排序算法。

不同的排序算法适用于不同的场景,例如快速排序适用于大规模数据,而插入排序适用于部分有序的小规模数据。

分析数据特性:了解待排序数据的特性有助于选择最优的排序算法。

如果数据基本有序,可以考虑使用插入排序等适应性较强的算法。

考虑稳定性:稳定性是指相等元素的相对顺序在排序前后保持不变。

在需要保持相等元素相对次序的场景中,选择稳定排序算法,如归并排序。

内存占用和性能:不同的排序算法对内存占用和性能有不同的要求。

在空间有限的情况下,可以选择原地排序算法,例如快速排序。

常见排序算法及其做法1. 冒泡排序冒泡排序是一种简单的排序算法,它会多次遍历数组,比较相邻的元素并交换它们,使得较大的元素逐渐“冒泡”到数组的尾部。

做法:从第一个元素开始,依次比较相邻元素,如果顺序不对则交换。

重复上述过程,直到没有需要交换的元素。

2. 插入排序插入排序是一种逐步构建有序序列的排序算法。

它适用于小规模数据或者部分有序的数据。

做法:从第二个元素开始,将当前元素插入到已经有序的序列中的正确位置。

重复上述过程,直到所有元素有序。

3. 选择排序选择排序是一种简单直观的排序算法,每次选择最小的元素与当前位置进行交换。

做法:找到数组中最小的元素,与第一个元素交换位置。

在剩余的元素中找到最小的元素,与第二个元素交换位置。

重复上述过程,直到所有元素有序。

4. 快速排序快速排序是一种分治的排序算法,通过选择一个基准元素将数组划分为两个子数组,然后对子数组进行递归排序。

做法:选择一个基准元素,将数组分成两个子数组,左边小于基准,右边大于基准。

对左右子数组进行递归排序。

合并两个有序子数组。

数据结构与算法分析课后习题答案

数据结构与算法分析课后习题答案

数据结构与算法分析课后习题答案第一章:基本概念一、题目:什么是数据结构与算法?数据结构是指数据在计算机中存储和组织的方式,如栈、队列、链表、树等;而算法是一系列解决问题的清晰规范的指令步骤。

数据结构和算法是计算机科学的核心内容。

二、题目:数据结构的分类有哪些?数据结构可以分为以下几类:1. 线性结构:包括线性表、栈、队列等,数据元素之间存在一对一的关系。

2. 树形结构:包括二叉树、AVL树、B树等,数据元素之间存在一对多的关系。

3. 图形结构:包括有向图、无向图等,数据元素之间存在多对多的关系。

4. 文件结构:包括顺序文件、索引文件等,是硬件和软件相结合的数据组织形式。

第二章:算法分析一、题目:什么是时间复杂度?时间复杂度是描述算法执行时间与问题规模之间的增长关系,通常用大O记法表示。

例如,O(n)表示算法的执行时间与问题规模n成正比,O(n^2)表示算法的执行时间与问题规模n的平方成正比。

二、题目:主定理是什么?主定理(Master Theorem)是用于估计分治算法时间复杂度的定理。

它的公式为:T(n) = a * T(n/b) + f(n)其中,a是子问题的个数,n/b是每个子问题的规模,f(n)表示将一个问题分解成子问题和合并子问题的所需时间。

根据主定理的不同情况,可以得到算法的时间复杂度的上界。

第三章:基本数据结构一、题目:什么是数组?数组是一种线性数据结构,它由一系列具有相同数据类型的元素组成,通过索引访问。

数组具有随机访问、连续存储等特点,但插入和删除元素的效率较低。

二、题目:栈和队列有什么区别?栈和队列都是线性数据结构,栈的特点是“先进后出”,即最后压入栈的元素最先弹出;而队列的特点是“先进先出”,即最先入队列的元素最先出队列。

第四章:高级数据结构一、题目:什么是二叉树?二叉树是一种特殊的树形结构,每个节点最多有两个子节点。

二叉树具有左子树、右子树的区分,常见的有完全二叉树、平衡二叉树等。

数据结构课后习题答案-完整版

数据结构课后习题答案-完整版

数据结构课后习题答案-完整版下面是《数据结构课后习题答案-完整版》的内容:---第一章:数组1. 题目:给定一个整数数组,判断是否存在两个元素之和等于目标值。

答案:使用双指针法,首先将数组排序,然后设置左指针指向数组头部,右指针指向数组尾部。

如果左指针和右指针指向的元素之和小于目标值,则左指针右移;如果大于目标值,则右指针左移;如果等于目标值,则找到了两个元素之和等于目标值的情况。

2. 题目:给定一个整数数组和一个目标值,找出数组中和为目标值的两个数的下标。

答案:使用哈希表,在遍历数组的过程中,将每个元素的值和下标存储在哈希表中。

遍历到当前元素时,检查目标值与当前元素的差值是否在哈希表中,如果存在,则找到了两个数的下标。

---第二章:链表1. 题目:给定一个链表,判断链表中是否存在环。

答案:使用快慢指针法,定义两个指针,一个指针每次向前移动一个节点,另一个指针每次向前移动两个节点。

如果存在环,则两个指针必定会相遇。

2. 题目:给定一个链表,删除链表的倒数第N个节点。

答案:使用双指针法,定义两个指针,一个指针先移动N个节点,然后两个指针同时向前移动,直到第一个指针到达链表尾部。

此时第二个指针指向的节点即为要删除的节点。

---第三章:栈和队列1. 题目:设计一个栈,使得可以在常数时间内获取栈中的最小元素。

答案:使用辅助栈来保存当前栈中的最小元素。

每次压栈操作时,将当前元素与辅助栈的栈顶元素比较,只有当前元素较小才将其压入辅助栈。

2. 题目:设计一个队列,使得可以在常数时间内获取队列中的最大元素。

答案:使用双端队列来保存当前队列中的最大值。

每次入队操作时,将当前元素与双端队列的末尾元素比较,只有当前元素较大才将其压入双端队列。

---第四章:树和二叉树1. 题目:给定一个二叉树,判断它是否是平衡二叉树。

答案:通过递归遍历二叉树的每个节点,计算每个节点的左子树高度和右子树高度的差值。

如果任意节点的差值大于1,则该二叉树不是平衡二叉树。

数据结构第三章习题及解答

数据结构第三章习题及解答

数据结构第三章习题及解答Chap3一选择题1. 对于栈操作数据的原则是(B)。

A. 先进先出B. 后进先出C. 后进后出D. 不分顺序2. 在作进栈运算时,应先判别栈是否( B ),在作退栈运算时应先判别栈是否( A )。

当栈中元素为n个,作进栈运算时发生上溢,则说明该栈的最大容量为( B )。

A. 空B. 满C. 上溢D. 下溢③: A. n-1 B. n C. n+1 D. n/23. 一个栈的输入序列为123…n,若输出序列的第一个元素是n,输出第i(1<=i<=n)个元素是(B)。

A. 不确定B. n-i+1C. iD. n-i4. 有六个元素6,5,4,3,2,1 的顺序进栈,问下列哪一个不是合法的出栈序列?(C)A. 5 4 3 6 1 2B. 4 5 3 1 2 6C. 3 4 6 5 2 1D. 2 34 15 65. 设栈的输入序列是1,2,3,4,则(D)不可能是其出栈序列。

A. 1,2,4,3,B. 2,1,3,4,C. 1,4,3,2,D. 4,3,1,2,6. 设一个栈的输入序列是1,2,3,4,5,则下列序列中,是栈的合法输出序列的是(D)。

A. 5 1 2 3 4B. 4 5 1 3 2C. 4 3 1 2 5D.3 2 1 5 47. 设有三个元素X,Y,Z顺序进栈(进的过程中允许出栈),下列得不到的出栈排列是( C)。

A.XYZ B. YZX C. ZXYD. ZYX8. 执行完下列语句段后,i值为:(B)int f(int x){ return ((x>0) ? x* f(x-1):2);}int i ;i =f(f(1));A.2 B. 4 C. 8 D. 无限递归9. 用不带头结点的单链表存储队列时,其队头指针指向队头结点,其队尾指针指向队尾结点,则在进行删除操作时( D )。

A.仅修改队头指针 B. 仅修改队尾指针C. 队头、队尾指针都要修改D. 队头,队尾指针都可能要修改10. 递归过程或函数调用时,处理参数及返回地址,要用一种称为( C )的数据结构。

数据结构习题答案第三章

数据结构习题答案第三章

void DSqStack <ElemType>::Pop(int i) {//i 的取值为 0 或 1
if (i == 0) top[0]--;
else top[1]++;
}//Pop
5. (1). A, C, D (2). 从左到右读序列,任何时候累计 I 的个数都应大于等于 O 的个数。 (3). bool islegal(char *a) {
newbase[k + 10] = base[k];
delete[] base;
base = newbase;
size += 10;
top[1] += 10;
}
if (i == 0)
base[++top[0]] = e;
else
base[--top[1]] = e;
}//Push
//出栈,弹出栈顶元素。先决条件是栈非空。 template <class ElemType>
ElemType & Top(int i) const;
void Push(const ElemType &e,int i);
void Pop(int i);
private:
//双向栈类的数据成员
ElemType *base; //基地址指针
int top[2];
//栈顶指针
int size;
//向量空间大小
//void Leabharlann lear();//bool Empty() const;
//int Length() const;
//ElemType & GetHead() const;

数据结构第2和3章应用题答案

数据结构第2和3章应用题答案

数据结构第2和3章应用题答案数据结构应用题答案第2章线性表1.设指针变量p指向双向链表中结点A,指针变量q指向被插入结点B,要求给出在结点A 的后面插入结点B的操作序列(设双向链表中结点的两个指针域分别为llink和rlink)。

答:操作序列如下:q->rlink = p->rlink ; p->rlink = q ;q->rlink->llink = q ; q->llink = p ;注意答案不唯一第3章栈和队列1.设有编号为1,2,3,4的四辆列车,顺序进入一个栈式结构的车站,具体写出这四辆列车开出车站的所有可能的顺序。

答:共计14种,分别是:1234, 1243, 1324, 1342, 1432,2134, 2143, 2341, 2314,2431, 3214, 3241, 3421, 43212.如果输入序列为1,2,3,4,5,6,试问能否通过栈结构得到以下两个序列:4,3,5,6,1,2和1,3,5,4,2,6;请说明为什么不能或如何才能得到。

答:(1)不能得到4,3,5,6,1,2 ;因为1,2,3,4入栈后;4,3出栈;得到序列4,3;栈中还有1,2;5入栈后即出栈,得到序列4,3,5;6入栈后即出栈,得到序列4,3,5,6;此时,栈中还有1,2;必须2先出栈,然后1再出栈,1不可能在2之前出栈。

故而得不到该序列。

(2)能得到输出顺序为1,3,5,4,2,6的序列。

得到的操作如下:1入栈后即出栈,得到序列1;2,3入栈后3即出栈,得到序列1,3;4,5入栈后,5出栈,4出栈,得到序列1,3,5,4;2出栈,得到序列1,3,5,4,2;6入栈后即出栈,得到序列1,3,5,4,2,6。

3.假设正读和反读都相同的字符序列为“回文”,例如,‘abba’和‘abcba’是回文,‘abcde’和‘ababab’则不是回文。

假设一字符序列已存入计算机,请用堆栈判断其是否为回文,简述算法。

数据结构与算法第3章课后答案

数据结构与算法第3章课后答案

数据结构与算法第3章课后答案第 3 章特殊线性表——栈、队列和串(2005-07-14) -第 3 章特殊线性表——栈、队列和串课后习题讲解1. 填空⑴设有⼀个空栈,栈顶指针为1000H,现有输⼊序列为1、2、3、4、5,经过push,push,pop,push,pop,push,push后,输出序列是(),栈顶指针为()。

【解答】23,1003H⑵栈通常采⽤的两种存储结构是();其判定栈空的条件分别是(),判定栈满的条件分别是()。

【解答】顺序存储结构和链接存储结构(或顺序栈和链栈),栈顶指针top= -1和top=NULL,栈顶指针top等于数组的长度和内存⽆可⽤空间⑶()可作为实现递归函数调⽤的⼀种数据结构。

【解答】栈【分析】递归函数的调⽤和返回正好符合后进先出性。

⑷表达式a*(b+c)-d的后缀表达式是()。

【解答】abc+*d-【分析】将中缀表达式变为后缀表达式有⼀个技巧:将操作数依次写下来,再将算符插在它的两个操作数的后⾯。

⑸栈和队列是两种特殊的线性表,栈的操作特性是(),队列的操作特性是(),栈和队列的主要区别在于()。

【解答】后进先出,先进先出,对插⼊和删除操作限定的位臵不同⑹循环队列的引⼊是为了克服()。

【解答】假溢出⑺数组Q[n]⽤来表⽰⼀个循环队列,front为队头元素的前⼀个位臵,rear为队尾元素的位臵,计算队列中元素个数的公式为()。

page: 2The Home of jetmambo - 第 3 章特殊线性表——栈、队列和串【解答】(rear-front+n)% n【分析】也可以是(rear-front)% n,但rear-front的结果可能是负整数,⽽对⼀个负整数求模,其结果在不同的编译器环境下可能会有所不同。

⑻⽤循环链表表⽰的队列长度为n,若只设头指针,则出队和⼊队的时间复杂度分别是()和()。

【解答】O(1),O(n)【分析】在带头指针的循环链表中,出队即是删除开始结点,这只需修改相应指针;⼊队即是在终端结点的后⾯插⼊⼀个结点,这需要从头指针开始查找终端结点的地址。

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

第三章排序一、选择题1.某内排序方法的稳定性是指( D )。

A.该排序算法不允许有相同的关键字记录、B.该排序算法允许有相同的关键字记录C.平均时间为0(n log n)的排序方法 D.以上都不对2.下面给出的四种排序法中( )排序法是不稳定性排序法。

A. 插入B. 冒泡C. 二路归并D. 快速排序3.下列排序算法中,其中( CD )是稳定的。

A. 堆排序,冒泡排序B. 快速排序,堆排序C. 直接选择排序,归并排序D. 归并排序,冒泡排序6.若要求尽可能快地对序列进行稳定的排序,则应选( B )。

A.快速排序 B.归并排序 C.冒泡排序12.排序趟数与序列的原始状态有关的排序方法是( D )排序法。

A.插入 B. 选择 C. 冒泡 D. 快速17.数据序列(8,9,10,4,5,6,20,1,2)只能是下列排序算法中的( C )的两趟排序后的结果。

A.选择排序 B.冒泡排序 C.插入排序18.数据序列(2,1,4,9,8,10,6,20)只能是下列排序算法中的( A )的两趟排序后的结果。

A. 快速排序B. 冒泡排序C. 选择排序D. 插入排序19.对一组数据(84,47,25,15,21)排序,数据的排列次序在排序的过程中的变化为(1) 84 47 25 15 21 (2) 15 47 25 84 21 (3) 15 21 25 8447 (4) 15 21 25 47 84,则采用的排序是 ( A )。

A. 选择B. 冒泡C. 快速D. 插入24.下列序列中,( D )是执行第一趟快速排序后所得的序列。

A. [68,11,18,69] [23,93,73]B. [68,11,69,23] [18,93,73]C. [93,73] [68,11,69,23,18]D. [68,11,69,23,18] [93,73]28.下列排序算法中,在待排序数据已有序时,花费时间反而最多的是( C )排序。

A.冒泡 C. 快速 D. 堆31. 就平均性能而言,目前最好的内排序方法是( D )排序法。

A. 冒泡 C. 交换 D. 快速36.从未排序序列中依次取出一个元素与已排序序列中的元素依次进行比较,然后将其放在已排序序列的合适位置,该排序方法称为( )排序法。

A. 插入B. 选择C. 希尔D. 二路归并37. 在排序算法中,每次从未排序的记录中挑出最小(或最大)关键码字的记录,加入到已排序记录的末尾,该排序方法是()。

A. 选择B. 冒泡C. 插入D. 堆38.用直接插入排序方法对下面四个序列进行排序(由小到大),元素比较次数最少的是()。

A. 94,32,40,90,80,46,21,69 B. 32,40,21,46,69,94,90,80 C. 21,32,46,40,80,69,90,94 D. 90,69,80,46,21,32,94,40 40. 若用冒泡排序方法对序列{10,14,26,29,41,52}从大到小排序,需进行()次比较。

A. 3B. 10C. 15D. 2543.对下列关键字序列用快速排序法进行排序时,速度最快的情形是()。

A. {21,25,5,17,9,23,30} B.{25,23,30,17,21,5,9}C. {21,9,17,30,25,23,5} D. {5,9,17,21,23,25,30}44.对关键码序列28,16,32,12,60,2,5,72快速排序,从小到大一次划分结果为( B )。

A. (2,5,12,16)28(60,32,72)B. (5,16,2,12)28(60,32,72)C. (2,16,12,5)28(60,32,72)D. (5,16,2,12)28(32,60,72)48. 快速排序方法在()情况下最不利于发挥其长处。

A. 要排序的数据量太大B. 要排序的数据中含有多个相同值C. 要排序的数据个数为奇数D. 要排序的数据已基本有序三、填空题1.若不考虑基数排序,则在排序过程中,主要进行的两种基本操作是关键字的______和记录的_____。

3. 属于不稳定排序的有__________。

6.直接插入排序用监视哨的作用是_______。

7.对n个记录的表r[1..n]进行简单选择排序,所需进行的关键字间的比较次数为_______。

13.从平均时间性能而言,__________排序最佳15.快速排序在_____的情况下最易发挥其长处。

类似本题的另外叙述有:(1)快速排序法在_____情况下最不利于发挥其长处,在_____情况下最易发挥其长处。

16.在数据表有序时,快速排序算法的时间复杂度是____。

参考答案:一、选择题部分答案解释如下:18. 对于后三种排序方法两趟排序后,序列的首部或尾部的两个元素应是有序的两个极值,而给定的序列并不满足。

20. 本题为步长为3的一趟希尔排序。

24.枢轴是73。

64. 因组与组之间已有序,故将n/k个组分别排序即可,基于比较的排序方法每组的时间下界为O (klog2k),全部时间下界为O(nlog2k)。

二、判断题部分答案解释如下:5. 错误。

例如冒泡排序是稳定排序,将4,3,2,1按冒泡排序排成升序序列,第一趟变成3,2,1,4,此时3就朝向最终位置的相反方向移动。

12. 错误。

堆是n个元素的序列,可以看作是完全二叉树,但相对于根并无左小右大的要求,故其既不是二叉排序树,更不会是平衡二叉树。

22. 错误。

待排序序列为正序时,简单插入排序比归并排序快。

三、填空题1. 比较,移动2.生成有序归并段(顺串),归并3.希尔排序、简单选择排序、快速排序、堆排序等4. 冒泡,快速5. (1)简单选择排序 (2)直接插入排序(最小的元素在最后时)6. 免去查找过程中每一步都要检测整个表是否查找完毕,提高了查找效率。

7. n(n-1)/28.题中p指向无序区第一个记录,q指向最小值结点,一趟排序结束,p和q所指结点值交换,同时向后移p指针。

(1)!=null (2)p->next (3)r!=null (4)r->data<q->data (5)r->next (6)p->next9. 题中为操作方便,先增加头结点(最后删除),p指向无序区的前一记录,r 指向最小值结点的前驱,一趟排序结束,无序区第一个记录与r所指结点的后继交换指针。

(1)q->link!=NULL (2)r!=p (3)p->link (4)p->link=s(5)p=p->link10.(1)i<n-i+1 (2)j<=n-i+1 (3)r[j].key<r[min].key (4)min!=i (5)max==i (6)r[max]<-->r[n-i+1]11.(1)N (2)0 (3)N-1 (4)1 (5)R[P].KEY<R[I].KEY (6)R[P].LINK(7)(N+2)(N-1)/2(8)N-1 (9)0 (10)O(1)(每个记录增加一个字段) (11)稳定(请注意I的步长为-1)12. 3,(10,7,-9,0,47,23,1,8,98,36)13.快速14.(4,1,3,2,6,5,7)15.最好每次划分能得到两个长度相等的子文件。

设文件长度n=2k-1,第一遍划分得到两个长度?n/2?的子文件,第二遍划分得到4个长度?n/4?的子文件,以此类推,总共进行k=log(n+1)遍划分,各子文件长度均为1,排序结束。

216.O(n2)17. O(nlogn)218.(1)2*i (2)r[j].key>r[j+1].key (3)true (4)r[j] (5)2*i19.(1)2*i (2)j<=r (3)j←j+1 (4)x.key>heap[j].key (5)i←j(6)j←2*i (7)x20.(1)j:=2*i (2)finished:=false (3)(r[j].key>r[j+1].key) (4)r[i]:=r[j](5)i:=j(6) j:=2*i (7)r[i]:=t; (8)s if t(r,i,n) (9)r[1]:=r[i](10)s if t(r,1,i-1)21. ④是堆 (1)选择 (2)筛选法 (3)O(nlog2n) (4)O(1)22. (1) 选择 (2)完全二叉树 (3)O(Nlog2N) (4)O(1) (5)满足堆的性质23.(1)finish:=false (2)h[i]:=h[j]; i:=j; j:=2*j; (3)h[i]:=x(4)h,k,n (5)s if t(h,1,r-1)24. {D,Q,F,X,A,P,B,N,M,Y,C,W}25. (1)p[k]:=j (2)i:=i+1 (3)k=0 (4)m:=n (5)m<n (6)a[i]:=a[m] (7)a[m]:=t26. 程序(a)(1)true (2)a[i]:=t (3)2 TO n step 2 (4)true (5)NOT flag程序(b)(1)1 (2)a[i]=t (3)(i=2;i<=n;i+=2) (4)1(5)flag27.(Q,A,C,S,Q,D,F,X,R,H,M,Y),(F,H,C,D,Q,A,M,Q,R,S,Y,X)28. 初始归并段(顺串)29. 初始归并段,初始归并段,减少外存信息读写次数(即减少归并趟数),增加归并路数和减少初始归并段个数。

30. ⎡n/m⎤31.(1)m,j-1 (2) m:=j+1 (3)j+1,n (4) n:=j-1 最大栈空间用量为O(logn)。

四、应用题1. 假设含n个记录的序列为{ R1, R2, …,Rn},其相应的关键字序列为{ K1,K 2, …,Kn},这些关键字相互之间可以进行比较,即在它们之间存在着这样一个关系Ks1≤Ks2≤…≤Ksn,按此固有关系将n个记录序列重新排列为{ Rs1,Rs2, …,Rsn}。

若整个排序过程都在内存中完成,则称此类排序问题为内部排序。

3. 这种说法不对。

因为排序的不稳定性是指两个关键字值相同的元素的相对次序在排序前、后发生了变化,而题中叙述和排序中稳定性的定义无关,所以此说法不对。

对4,3,2,1起泡排序就可否定本题结论。

4. 可以做到。

取a与b进行比较,c与d进行比较。

设a>b,c>d(a<b和c<d情况类似),此时需2次比较,取b和d比较,若b>d,则有序a>b>d;若b<d时则有序c>d>b,此时已进行了3次比较。

再把另外两个元素按折半插入排序方法,插入到上述某个序列中共需4次比较,从而共需7次比较。

相关文档
最新文档