本题10分栈与队列的区别和共同点是什么队列主要
数据结构试题及答案_经典期末试题

一、一、单选题(每题 2 分,共20分)1. 1.栈和队列的共同特点是( )。
A.只允许在端点处插入和删除元素B.都是先进后出C.都是先进先出D.没有共同点2. 2.用链接方式存储的队列,在进行插入运算时( ).A. 仅修改头指针B. 头、尾指针都要修改C. 仅修改尾指针D.头、尾指针可能都要修改3. 3.以下数据结构中哪一个是非线性结构?( )A. 队列B. 栈C. 线性表D. 二叉树4. 4.设有一个二维数组A[m][n],假设A[0][0]存放位置在644(10),A[2][2]存放位置在676(10),每个元素占一个空间,问A[3][3](10)存放在什么位置?脚注(10)表示用10进制表示。
A.688 B.678 C.692 D.6965. 5.树最适合用来表示( )。
A.有序数据元素B.无序数据元素C.元素之间具有分支层次关系的数据D.元素之间无联系的数据6. 6.二叉树的第k层的结点数最多为( ).A.2k-1 B.2K+1 C.2K-1 D. 2k-17.7.若有18个元素的有序表存放在一维数组A[19]中,第一个元素放A[1]中,现进行二分查找,则查找A[3]的比较序列的下标依次为( )A. 1,2,3B. 9,5,2,3C. 9,5,3D. 9,4,2,38.8.对n个记录的文件进行快速排序,所需要的辅助存储空间大致为A. O(1)B. O(n)C. O(1og2n)D. O(n2)9.9.对于线性表(7,34,55,25,64,46,20,10)进行散列存储时,若选用H(K)=K %9作为散列函数,则散列地址为1的元素有()个,A.1 B.2 C.3 D.410.10.设有6个结点的无向图,该图至少应有( )条边才能确保是一个连通图。
A.5B.6C.7D.8二、二、填空题(每空1分,共26分)1. 1.通常从四个方面评价算法的质量:_________、_________、_________和_________。
栈和队列定义以及各基本操作的简要描述;

栈和队列是计算机科学中常用的数据结构,它们分别具有特定的特点和用途。
下面我们将对栈和队列的定义以及它们各自的基本操作进行简要描述。
一、栈的定义及基本操作1. 栈的定义栈是一种具有后进先出(LIFO)特点的线性数据结构,它可以看作是只能在一端进行插入和删除操作的特殊线性表。
栈通常具有入栈(push)和出栈(pop)两种基本操作。
2. 入栈(push)操作入栈操作是将元素压入栈顶的过程,新元素将会成为栈顶元素,栈的大小加1。
3. 出栈(pop)操作出栈操作是将栈顶元素弹出的过程,栈的大小减1,同时返回栈顶元素的数值。
4. 其他基本操作除了入栈和出栈操作外,栈还常常具有获取栈顶元素(top)、判断栈空(empty)、获取栈大小(size)等基本操作。
二、队列的定义及基本操作1. 队列的定义队列是一种具有先进先出(FIFO)特点的线性数据结构,它可以看作是只能在一端进行插入操作,在另一端进行删除操作的特殊线性表。
队列通常具有入队列(enqueue)和出队列(dequeue)两种基本操作。
2. 入队列(enqueue)操作入队列操作是将元素添加到队列的末尾的过程,新元素将成为队列中的最后一个元素,队列的大小加1。
3. 出队列(dequeue)操作出队列操作是将队列中的第一个元素移除的过程,队列的大小减1,同时返回被移除的元素的数值。
4. 其他基本操作除了入队列和出队列操作外,队列还常常具有获取队列头元素(front)、判断队列空(empty)、获取队列大小(size)等基本操作。
总结:栈和队列分别具有特定的特点和操作,栈适合于后进先出的场景,例如递归函数调用、表达式求值等;队列适合于先进先出的场景,例如任务调度、缓冲队列等。
掌握栈和队列的定义及基本操作对于合理地设计和实现算法,提高程序运行效率具有重要意义。
由于栈和队列具有不同的特点和功能,它们在计算机科学中被广泛运用,常常用来解决各种实际问题。
接下来我们将扩展对栈和队列的运用场景、常见应用以及优缺点的讨论。
数据结构--栈和队列基础知识

数据结构--栈和队列基础知识⼀概述栈和队列,严格意义上来说,也属于线性表,因为它们也都⽤于存储逻辑关系为 "⼀对⼀" 的数据,但由于它们⽐较特殊,因此将其单独作为⼀篇⽂章,做重点讲解。
既然栈和队列都属于线性表,根据线性表分为顺序表和链表的特点,栈也可分为顺序栈和链表,队列也分为顺序队列和链队列,这些内容都会在本章做详细讲解。
使⽤栈结构存储数据,讲究“先进后出”,即最先进栈的数据,最后出栈;使⽤队列存储数据,讲究 "先进先出",即最先进队列的数据,也最先出队列。
⼆栈2.1 栈的基本概念同顺序表和链表⼀样,栈也是⽤来存储逻辑关系为 "⼀对⼀" 数据的线性存储结构,如下图所⽰。
从上图我们看到,栈存储结构与之前所了解的线性存储结构有所差异,这缘于栈对数据 "存" 和 "取" 的过程有特殊的要求:1. 栈只能从表的⼀端存取数据,另⼀端是封闭的;2. 在栈中,⽆论是存数据还是取数据,都必须遵循"先进后出"的原则,即最先进栈的元素最后出栈。
拿图 1 的栈来说,从图中数据的存储状态可判断出,元素 1 是最先进的栈。
因此,当需要从栈中取出元素 1 时,根据"先进后出"的原则,需提前将元素 3 和元素 2 从栈中取出,然后才能成功取出元素 1。
因此,我们可以给栈下⼀个定义,即栈是⼀种只能从表的⼀端存取数据且遵循 "先进后出" 原则的线性存储结构。
通常,栈的开⼝端被称为栈顶;相应地,封⼝端被称为栈底。
因此,栈顶元素指的就是距离栈顶最近的元素,拿下图中的栈顶元素为元素 4;同理,栈底元素指的是位于栈最底部的元素,下中的栈底元素为元素 1。
2.2 进栈和出栈基于栈结构的特点,在实际应⽤中,通常只会对栈执⾏以下两种操作:向栈中添加元素,此过程被称为"进栈"(⼊栈或压栈);从栈中提取出指定元素,此过程被称为"出栈"(或弹栈);2.3 栈的具体实现栈是⼀种 "特殊" 的线性存储结构,因此栈的具体实现有以下两种⽅式:1. 顺序栈:采⽤顺序存储结构可以模拟栈存储数据的特点,从⽽实现栈存储结构。
浅谈数据结构系列栈和队列

浅谈数据结构系列栈和队列计算机程序离不开算法和数据结构,在数据结构算法应⽤中,栈和队列应⽤你⽐较⼴泛,因为两者在数据存放和读取⽅⾯效率⽐较⾼,本章节重点讲解两者的基本概念和实现。
基本概念栈:是⼀种先进后出,后进先出的数据结构,本质上是线性表,只是限制仅允许在表的⼀段进⾏插⼊和删除⼯作。
此端为栈顶,这是在栈中应⽤很关键的概念。
所有数据的处理都是在栈顶进⾏的,进栈时,栈中元素增加,栈顶上移⼀位,出栈时栈顶下移⼀位。
应⽤中⽐如:洗碗,每次洗⼲净的碗放在上⾯-进栈,取碗,从顶上取出⼀个-出栈;装⼦弹-进栈,开枪-出栈。
队列:是⼀种先进先出的数据结构,同样是线性表,允许在表⼀段进⾏插⼊(队尾),⽽表的另⼀端进⾏删除⼯作(队头)。
应⽤中⽐如:购物-先到的先购物,晚到的在队尾后买物品。
存储结构因为在c++中已经有实现的stack和queue,我们就以程序中封装的程序进⾏解读。
1、顺序存储结构数组本质上是顺序存储结构,所以在栈和队列的顺序存储结构上的实现,⽤数组实现即可,也就是在数组基础上进⾏⼆次封装,也就意味着会有溢出的现象。
a.栈的顺序存储结构:push,直接添加⼀个元素s[n]到数组,pop直接返回s[n-1]1 template<typename T>2class MyStack3 {4 T item[] ;5int number;6int Max;7 MyStack()8 {9 Max= 20;10 item = T[20];11 number = 0;12 }13//⼊栈14void MyStack::Push(T _item)15 {16//如果超过数组⼤⼩,则重新申请控件17if (number == Max) Resize(2 * Max);18//number记录数组中个数,同时将push的元素放在数组最后⾯。
先赋值然后number++.19 item[number++] = _item;20 }21//出栈22 T MyStack::Pop()23 {24//先——再获取元素.25 T temp = item[--number];26//其他设置为kong27 item[number] = default(T);28if (number > 0 && number == Max / 4) Resize(Max / 2);29return temp;30 }3132void MyStack::Resize(int capacity)33 {34 T[] temp = new T[capacity];35for (int i = 0; i < Max; i++)36 {37 temp[i] = item[i];38 }39 item = temp;40 }41 };View Code当我们缩⼩数组的时候,采⽤的是判断1/4的情况,这样效率要⽐1/2要⾼,因为可以有效避免在1/2附件插⼊,删除,插⼊,删除,从⽽频繁的扩⼤和缩⼩数组的情况。
数据结构复习题集[耿国华(第二版)版C语言描述]
![数据结构复习题集[耿国华(第二版)版C语言描述]](https://img.taocdn.com/s3/m/8507a4b63b3567ec112d8a32.png)
第一章复习题1.简述顺序存储结构与链式存储结构在表示数据元素之间关系上的主要区别。
答:在顺序结构中,逻辑关系上相邻的两个元素在物理位置上也相邻。
而链式存储结构中,数据元素之间关系是由结点中指针指示的。
2.数据结构是一门……的学科。
3.在数据结构中,从逻辑上可以把数据结构分成〔 C 〕。
A、动态结构与静态结构B、紧凑结构和非紧凑结构C、线性结构和非线性结构D、部结构和外部结构4.编写一个函数,用不多于3n/2的平均比拟次数,在一个数组中找出最大和最小值元素。
void maxmin(int a[],int n){max=min=a[0];for(i=1;i<n;i++){if(a[i]>max) max=a[i];else if(a[i]<min) min=a[i];}printf(“max=%d, min=%d〞,max, min);}第二章复习题1.下述哪一条是顺序存储结构的优点?〔 A 〕A.存储密度大 B.插入运算方便C.删除运算方便 D.可方便地用于各种逻辑结构的存储表示2.下面关于线性表的表达中,错误的选项是哪一个?〔 B 〕A.线性表采用顺序存储,必须占用一片连续的存储单元。
B.线性表采用顺序存储,便于进展插入和删除操作。
C.线性表采用存储,不必占用一片连续的存储单元。
D.线性表采用存储,便于插入和删除操作。
3.线性表是具有n个〔 C 〕的有限序列〔n>=0〕。
A.表元素 B.字符 C.数据元素 D.数据项4.假设某线性表最常用的操作是存取任一指定序号的元素和在最后进展插入和删除运算,那么利用〔 A 〕存储方式最节省时间。
A.顺序表 B.单循环链表C.带头结点的双循环链表 D.双链表5.某线性表中最常用的操作是在最后一个元素之后插入一个元素和删除第一个元素,那么采用〔 D 〕存储方式最节省运算时间。
A.单链表 B.仅有头指针的单循环链表C.双链表 D.仅有尾指针的单循环链表6.假设某表最常用的操作是在最后一个结点之后插入一个结点或删除最后一个结点。
(整理)栈和队列

第三章栈和队列1.何为栈和队列?简述两者的区别和联系。
栈:是一种只允许在一端进行插入和删除的线性表,它是一种操作受限的线性表。
在表中只允许进行插入和删除的一端称为栈顶(top),另一端称为栈底(bottom)。
栈顶元素总是最后入栈的,因而是最先出栈;栈底元素总是最先入栈的,因而也是最后出栈。
因此,栈也被称为“后进先出”的线性表。
队列:队列(queue)是一种只允许在一端进行插入,而在另一端进行删除的线性表,它是一种操作受限的线性表。
在表中只允许进行插入的一端称为队尾(rear),只允许进行删除的一端称为队头(front)。
队头元素总是最先进队列的,也总是最先出队列;队尾元素总是最后进队列,因而也是最后出队列。
因此,队列也被称为“先进先出”表。
区别和联系:从数据结构上看,栈和队列也是线性表,不过是两种特殊的线性表。
栈只允许在表的一端进行插入或删除操作,队列只允许在表的一端进行插入操作、而在另一端进行删除操作。
因而,栈和队列也可以被称作为操作受限的线性表。
2.若依次读入数据元素序列{a,b,c,d}进栈,进栈过程中允许出栈,试写出各种可能的出栈元素序列。
可能的出栈序列:a,b,c,d b,c,d,a b,a,c,d a,b,d,c a,d,c,b a,c,b,d a,c,d,b b,d,c,a b,a,d,c c,d,b,a c,b,d,a c,b,a,d d,c,b,a 等3.试写一个算法,识别依次读入的一个以@为结束符的字符序列是否为形如‘序列1—序列2’模式的字符序列。
其中序列1和序列2中都不含字符‘&’,且序列2是序列1的逆序列。
例如,‘a+b&b+a’是属该模式的字符序列,而’1+3&3-1’则不是。
Status Model(){//识别依次读入的一个以@为结束符的字符序列是否为形如‘序列1&序列2’模式的字符序列//序列1和序列2中不包含字符‘&’,序列1是序列2的逆序列InitStack(s); c=getchar();while (c!='&') {Push(s,c); c=getchar();}c=getchar();while (c!='@'&&!StackEmpty(s)) {Pop(s,x);if (c==x) c=getchar();else return FALSE;}if (c=='@' && StackEmpty(s)) return TRUE;else return FALSE;}4.试写一个判别表达式中开、闭括号是否配对出现的算法。
浅谈栈和队列
浅谈栈和队列摘要: 栈和队列是在程序设计中被广泛使用的两种线性数据结构,它们的特点在于基本操作的特殊性,栈必须按“后进先出”的规则进行操作,而队列必须按“先进先出”的规则进行操作。
和线性表相比,它们的插入和删除操作受更多的约束和限定,故又称为限定性的线性表结构。
关键词:栈和队列; 数据结构; 线性表; 抽象数据类型Stack and QueueAbstract: Stack as a kind of data structure, it is a kind of can in the end of the insert and delete operation of the special linear list. Queue is a special kind of linear list, it is allowed only in the front of the table (front) to delete operation, but in the table after end (rear) insertion operation. For insertion operation of the end called rear, to delete operation of the end called team head. The queue no element, called empty queue.Key words: Stack and queue ;Data structure ; Linear list; Abstract data type0 引言栈(Stack)是限定只能在表的一端进行插入和删除操作的线性表。
队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。
在队列这种数据结构中,最先插入的元素将是最先被删除的元素;反之最后插入的元素将是最后被删除的元素,因此队列又称为“先进先出”(FIFO—first in first out)的线性表。
队列、栈、链表简要介绍
队列、栈、链表简要介绍————拂晓队列、栈是两种编程中常用的线性数据结构,在某些问题中适时地使用队列或栈可以使问题的思路变得非常简单、清晰,下面分别介绍这两种数据结构。
一队列:队列,就如其名字所表述的意思,就是排队,比如我们在食堂打饭排的队,第一个人在队头买饭,后面的人都在后面排着,第一个人走了,第二个人就变成队的头部,而如果有其他的同学过来打饭,那么他就要成为新的队尾,同时队伍长度也相应变长。
如果我们把打饭排的队用一个整型数组a[N]表示,第一个学生是a[1],第i个学生是a[i],一开始第一个学生是队头,也就是a[1]为头,当第一个学生走了之后第二个学生就成了队头,也就是a[2]变成了头,所以我们可以定义一个变量int head,并将其初值赋成1,当一个学生走了之后就把它加1,这样就实现了一个学生走了之后后面的学生为新的队头,如果现在有m个学生,那么现在的队尾就是a[m],如果来了下一个学生,那么队尾就要变成a[m+1],所以可以再定义一个变量int tail,并赋初值0,因为最初是没有学生来买饭的,每当有一个学生到来,就将tail+1,这样就可以表示队伍的尾部又向后移了一位,由于head和tail都是随时变化的,所以想要判断一个队伍是否为空,需要判断head与tail的关系,如果它们相等,说明队首和队尾是同一个人,也就说明队伍里只有一个人,如果这个人走了,那么head 要加1,这时队伍里就正好没有人了,这时head和tail的关系为head>tail,这样我们就可以判断队伍是否为空了。
二栈:栈表示一种后进先出的数据结构,类似于生活中“一摞”的东西,比如一摞盘子,最先放的在最下面,要最后才能取出,最后放的在最上面,可以直接取出并且每次只能取出最上面的那个,再比如一个乒乓球粗细的小筒,往里面放乒乓球,我们每次可以取出的是我们之前放入的最后一个球,如果同样用一个数组a[N] 来表示这些筒中的乒乓球,a[1]表示第1个乒乓球,a[2]表示第二个乒乓球,…,用一个变量top来表示最上面的那个球,那么a[top]就指向最上面的乒乓球,如果只有一个top,我们就只能找到最上面的乒乓球,这样就符合了栈的要求,这样我们就用一个数组表示了“一摞”乒乓球,也就是一个栈,当一个新的元素到来时,我们就将top加1,并将a[top]赋为新元素的值,当一个元素失去利用价值后,我们就将top减1,这样就等价于将这个元素从栈中删除了,为了防止意外修改栈中除栈顶以外的元素从而破坏逻辑,我们一般除了top外不使用其他变量去作为下标访问栈。
数据结构(专)阶段练习2
华东理工大学网络学院(专科)《数据结构》------第3章、第4章、第5章班级学号姓名成绩一、填空题(每空1分,共20分)1. 栈和队列是两种特殊的线性表,栈的特点是先进后出,表达式求值,栈的典型应用有和实现递归过程。
2. 在具有n个单元的循环队列中,队列满时共有n-1 个元素。
3. 若串的长度不能确定,可采用动态存储结构,为串值分配一个存储空间,同时建立一个串的描述子以指示串值的长度和串在存储空间中的位置,称该结构为堆/堆结构。
4. 稀疏矩阵一种常用的压缩存储方法称为三元组表方式,即每个三元组表中的元素由、行、列、值、三部分组成。
5. 二维数组A[10][20]采用列序为主方式存储,每个元素占10个存储单元,且A[0][0]的存储地址是2000,则A[6][12]的地址是3260 。
6.进栈序列为a,b,c,则通过出栈和进栈操作可能得到的a,b,c的不同的排列序列有5 种。
7. 广义表((a,b),c,d)的表头是(a, b) ,表尾是(c,d) 。
8.已知二维数组A[20][10]采用行序为主方式存储,每个元素占2个存储单元,并且A[10][5]的存储地址是1000,则A[18][9]的存储地址是1168 。
9. 广义表((((a),b),c),d)的表头是(((a),b),c) ,表尾是(d) 。
10. 设s=’YOU ARE JUDGING IT RIGHT OR WRONG’,顺序执行下列操作:SubString(sub1,s,1,8);SubString(sub2,s,20,5);StrCat(sub1,sub2); 则最后sub1的值为:’YOU ARE RIGHT’。
11. 假设用循环单链表实现队列,若队列非空,且队尾指针为R, 则将新结点S加入队列时,需执行下面语句:S->next=R->next ;R->next=S ;R=S 。
12.设有两个串p和q,求q在p中首次出现的位置的运算称作子串定位。
栈与队列,各有异同。
栈与队列,各有异同。
⾸先是两者的定义:栈也称为堆栈,是⼀种线性表。
栈的特性:最先放⼊栈中的内容最后被拿出来,最后放⼊栈中的内容最先被拿出来,被称为先进后出、后进先出。
队列也是⼀种特殊的线性表。
不同于栈所服从的先进后出的原则,队列的原则是先进先出。
队列在队头做删除操作,在队尾做插⼊操作。
然后是两者的异同点不同点:1.删除数据元素的位置不同,栈的删除操作在表尾进⾏,队列的删除操作在表头进⾏。
2.队列先进先出,栈先进后出。
3.顺序栈能够实现多栈空间共享,⽽顺序队列不能。
4.遍历数据速度不同。
栈只能从头部取数据,也就最先放⼊的需要遍历整个栈最后才能取出来。
队列则不同,它基于地址指针进⾏遍历,⽽且可以从头或尾部开始遍历⽆需开辟临时空间,速度要快的多。
相同点:1.都是。
2.插⼊操作都是限定在表尾进⾏。
3.都可以通过顺序结构和链式结构实现。
4.插⼊与删除的时间复杂度与空间复杂度上两者均相同。
再然后便是两者的表⽰和操作的实现栈表⽰和操作的实现:#include <iostream>#define MAXSIZE 100//基础容量using namespace std;typedef struct{SElemType *top;//栈顶指针SElemType *base;//栈底指针int stacksize;//栈可⽤最⼤容量}SqStack;Status InitStack(SqStack &S)//初始化栈{S.base=new SElemType[MAXSIZE];if(!s.base) exit(OVERFLOW);//内存分配失败S.top=s.base;S.stacksize=MAXSIZE;}Status Push(SqStack &S,SElemType e)//把元素e压⼊栈顶{if(S.top-S.base==S.stacksize) return ERROR;//栈满*S.top++=e;//栈顶指针+1return OK;}Status Pop(SqStack &s,SElemType &e)//取出栈顶元素,并删除栈顶{if(S.top==S.base)//top与base重合时,栈为空return ERROR;e=*--S.top;return OK;}SElemType GetTop(SqStack S){if(S.top!=S.base)return *(S.top-1);}队列表⽰和操作的实现:#ifndef STATICQUEUE_H_INCLUDED#define STATICQUEUE_H_INCLUDEDtemplate<class T>class StaticQueue{public:StaticQueue();StaticQueue(int size);~StaticQueue();void enqueue(T data);T dequeue();bool isEmpty();bool isFull();int count();void display();private:int rear;int front;int size;const static int DEFAULT;T* queue;};这些在课本上都有,下⾯说说遇到的问题:对于作业3,可以说是屡战屡败,屡败屡战了,先是⼀点思路都没有,再到后来⽼师提⽰后有⼀点思路,但还是错误百出,再到后来参照书上的⽅法,还是错误,最后终于发现问题。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、(本题10分)栈与队列的区别和共同点是什么?队列主要有哪两种物理实现? 答:
区别:栈在表尾进行插入和删除,具有“后进先出”的特点;队列在表尾插入,在表头删除,具有“先进先出”的特点;
共同点:栈和队列都是特殊的线性表,都是n 个数据元素的有限序列,都是数据结构的逻辑结构。
队列的物理实现:链队列和循环队列。
二、(本题10分)给出二叉树的定义,并画出具有3个结点的二叉树的所有形态。
答:所谓二叉树或者是空树,或者是如下定义的树:每个结点至多只有两棵子树,并且二叉树的子树有左右之分,其次序不能颠倒。
3个结点的二叉树的所有形态如下:
三、(本题15分)考虑下图:
1) 从顶点A 出发,求它的深度优先生成树(字母小的优先访问)。
2) 从顶点E 出发,求它的广度优先生成树(字母小的优先访问)。
3) 使用克鲁斯卡尔算法,求它的最小生成树(给出树的生成过程)。
答:深度优先生成树为:
广度优先生成树为:
最小生成树为:(因为有相同的权值,树的生成过程可能不相同)
评分标准:每小题5分。
四、(本题15分)假定一个待哈希存储的线性表为(32,75,29,63,48,94,25,46,18,70),哈希地址空间为0~12,若采用除留余数法H(K)=K % 13构造哈希函数,并使用链地址法处理冲突,试画出最后得到的哈希表,并求出平均查找长度。
解:
元素 哈希地址 查找次数
平均查找长度为(1*8+2*2)/10=1.2
评分标准: 画出哈希表得10分,平均查找长度得5分。
五、(本题15分)已知键值序列为{45,56,83,31,72,35,14,47,89,19},要求给出:
(1) 按键值排列次序构造一棵二叉排序树。
(2) 在等概率的情况下,该二叉排序树查找成功的平均查找长度。
(3) 针对上述10个键值,在不同的排列次序下所构造出的不同形态的二叉排序树中,
在最坏和最好情况下,二叉排序树的高度各是多少?
解:总分为15分,每一小步5分。
(1)
(2)在等概率情况下,该二叉排序树的平均检索长度是:
ASL=(1+2*2+3*4+4*3)/10=29/10=2.9
(3)对于上述10个键值,在最坏情况下,每个结点(除了叶子结点)只有右孩子(或者只有左孩子),高度为10。
在最好情况下,高度为└log 210┘+1=4。
六、(本题10分)设关键字序列为:49,38,66,90,75,10,20。
把这些关键字调整成堆顶元素取最小值的堆(写出过程)。
七、(本题10分)试设计一个递归算法(函数),判断二叉树T 是否是满二叉树,假设T 是以二叉链表存储。
typedef struct BiTNode{
TElemType data;
Struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
解答:
算法:
(1)如果二叉树T 是空树,则是满二叉树;
(2)如果二叉树T 非空,左子树或右子树不是满二叉树,则不是满二叉树;
(3)如果二叉树T 非空,左右子树都是满二叉树,但深度不一样,则T 不是满二叉树。
(4)如果二叉树T 非空,左右子树都是满二叉树,而且深度一样,则T 是满二叉树;
//该函数判断二叉树T 是否是满二叉树
//如果是满二叉树,返回TRUE ,Depth 返回该树的深度;
//否则返回FALSE ,Depth 无定义;
Boolean Check( BiTree T, int &Depth)
{ int ldepth, rdepth;
if( T==NULL) { Depth=0; return TRUE; }
if( Check(T->lchild, ldepth)==FALSE ) return FALSE;
if( Check(T->rchild,rdepth)==FALSE) return FALSE;
if( ldepth!=rdepth ) return FALSE;
Depth=ldepth+1; return TRUE;
八、(本题15分)在n个元素中,找出第k大的元素,最好是在O(n)的时间复杂性之内。
请设计数据结构,并在其上设计算法(函数),并给出时间复杂性分析。
答:可以借鉴快排算法来达到O(n) 。
static ITEM_select(ITEM [] a, int l, int r, int k)
{
while(r>l) {
int i = partition(a, l ,r); //partition后,比a[i]小的都在i左边,
//比a[i]大的都在i右边。
if(i==k) return a[k];
if(i<k) r=i-1; //从l到i-1做selection
if(i>k) l=i+1; //从i+1到r做selection
}
}
对于足够大的随机数组,每次partion会把数组分成大约相等的两半,那么每次问题size缩小一般,比较次数为n+n/2+n/ 4+.....+1=2n。
因此为O(n)。
注意select和quicksort不同,因为quicksort每次都要比较N,而select的比较次数是指数减少的,因此是O(n)而不是O(nlogn)。