前言: 这里是大一期末数据结构备考的一些做题记录,包含了一些知识点和题目,比较多,零散。
数组存储
二维数组地址问题
一维数组:
对一个有n个数据的一维数组: 设a0是下标为0的元素。
a0的存放地址设为p
, k
为数据元素占的字节数。
则有 数组中任意下标元素 ai 的地址= p+i*k
当数组为 row
行col
列的二位数组时,计算机中有行主序
和列主序
两种映射成一维数组的方法。
行主序的方法是:
存完一行再存下一行 。
设 &a[0][0] 为首地址
&a[i][j] = &a[0][0] + ( i * col + j)* k
理解: 在 a[i][j]
以前已经存放了i行
,每一行有col个元素,则有 i*col
, 在j
之前已经放 j
个元素。
列主序的方法是:
存放完一列再存下一列
a[i][j] 的地址为: & a [0] [0] + (j * row + i)*k
理解: 在 a[i][j]之前已经放了 j列
,每一列有row
个元素 ,则有 j*row
, 在j之前已经放了i
个元素。
- 4 行 5 列的二维数组 M (数组下标从 0 开始),M 按行优先顺序存储时元素 M[2][4] 的起始地址与 M 按列优先顺序存储时元素( )的起始地址相同。
A.M[3][2]
B.M[3][3]
C.M[2][3]
D.M[4][2]
按行存储时 M[2][4] = P(起始地址)+ (2 * 5+4)* k 按列存储时设为i,j 则有 P+(j * 4+i)k 也就是
25+4 = j*4+i 又 i<3,j<4 得 i=2,j=3 ;选择答案C
数组A中,每个数据元素长度为3个字节,行下标从1到8,列下标从1到10,数组首地址为ADDR,按行存放,那么元素A[5][8]的地址为
A.ADDR+225
B.ADDR+141
C.ADDR+222
D.ADDR+180
栈
- 一个栈的入栈序列为1,2,3,…,n ,其出栈序列是 p 1 ,p 2 ,p 3 ,…p n 。若p 2 = 3,则 p 3 可能取值的个数是()
A.n-3
B.n-2
C.n-1
D.无法确定
解析:当n=3时,p2=3,p1有可能为1,2 , 则p3也只剩下两个值,也就是n-1
当n>3时,p2=3,p1可能为1,2,4. 则p3的是除了3以外的任何一个。(p1 =1 ,p3=2,4,5…n , p1=2,4 同理) 也是n-1 。 选C
- 下列链表中最不适合用作链栈的是( )。
A.只有表头指针没有表尾指针的双向循环链表。
B.只有表尾指针没有表头指针的双向循环链表。
C.只有表头指针没有表尾指针的单循环链表。
D.只有表尾指针没有表头指针的单循环链表
解析: 在表头插入或删除元素时,要维护结构依然为循环链表,也就是要找表尾指针,需要O(n)的时间复杂度。 选择C
队列 :
- (多选) 实现双端队列(队头队尾都能插入和删除元素)的入队和出队操作时间复杂度都为O(1)的结构是
A.带有头尾指针的单链表
B.循环单链表
C.带有头尾指针的双向链表
D.带有头尾指针的顺序表
解析:
A: 在尾部删除元素要遍历队列不符合O(1)的要求 ,B同理。(队尾删除)选择C,D。
想做多一些关于栈的题目的可以移步:
栈的习题
二叉树
术语
度数: 树中节点的子树的个数称为该结点的度
二叉树性质
二叉树是一种每个节点至多有两个子树,即每个节点的度不大于2。
- 二叉树是有序树。(就算二叉树的某个结点只有一个孩子,都要区分左/右孩子。
- 二叉树不是树的特例。 两者是同属于树结构的两种不同类型
- 当结点为0或1时,既可以认为是树,也可以认为是二叉树。
- 非空二叉树中,第i层至多有 2 ( i − 1 ) 2^{(i-1)} 2(i−1) 结点
- 深度为k 的二叉树至多有
2
k
−
1
2^{k -1}
2k−1个结点(k>=1 )
(说明:上面的两条性质是以根节点为第一层计算的) - 对于任意一棵 二叉树,若其叶子结点数为n0 , 度为2的结点数为n2,则 :
n0 = n2+1
- 包含n个结点的二叉树高度/深度至少为 (log2n)+1
完全二叉树:
对于有n个节点的完全二叉树,如果按照从上至下,从左到右的顺序对所有结点从0开始编号,对于序号为i的结点来说,有:
(1)如果i>0, 则序号为i结点的左孩子结点的序号为2i+1 。
······· 如果i=0,则序号i为根节点。
(2)如果2i+1<n,则序号i的左孩子结点为2i+1。
· ····· 如果2i+1>=n,则该节点无左孩子
(3)如果2i+2<n,则序号为i的右孩子结点为2i+2 。
········如果2i+2>=n,则序号为i结点无右孩子。
- 在一棵度为 3 的树上,度为 3 的结点数为 3 个,度为 2 的结点数为 2 个,度为 1 的结点数为 2 个,则度为 0 的结点数为( )个。
解析:9个(画出来数数)
- 树最适合用来表示( 元素之间具有分支层次关系的数据 )。
- 假设一棵树的嵌套括号表示为 (a(b(e),c(f(h,i,j),g),d)),则该树上终端结点的个数为( )
a有3个孩子:b,c,d,b有左孩子e,c有f,g,f有三个孩子h,i,j 。
其中终端结点(也就是叶子节点)为:e,d,g,h,i,j共六个。6个
- 一棵完全二叉树上有1001个结点,其中叶子结点的个数是( )。
解析:
解法一:
二叉树n0+n1+n2 =1001 , 又由性质:n0=n2+1
;代入得2n2+n1=1001
因为是完全二叉树所以n1只能为1或者0,在这里n1就是0(要取整),所以 n2=500,n0=501 . 答案: 501
解法二:
解析
完全二叉树的最后一个结点的编号一定是1001,则它的父结点的编号为1001/2=500,则叶子结点个数为1001-500=501.
总结一下:完全二叉树的最后一个结点的编号是n,则它的父结点的编号为[n/2],则叶子结点个数为 n-[n/2]。
5.含有 n 个结点的二叉树,若采用二叉链表存储,则整个存储结构中只有( n-1
)个非空指针域,所以也就是有n+1个空指针域
个人认为可以理解为
n
个顶点,n-1
条边。 (树的基本性质)有边的代表有非空指真
- 已知先序序列和中序序列可确定一棵唯一的二叉树;
已知后序序列和中序序列可确定一棵唯一的二叉树;
已知先序序列和后序序列不能确定一棵唯一的二叉树。
先序遍历的第一个结点就是二叉树的根节点,在中序遍历的序列找到根节点的位置就可以划分处左右子树,再依次分下去可以构造出一棵唯一的二叉树
中序和后序同理
但是前序和后序中无法根据根结点划分左右子树,此时也就不能唯一确定一棵二叉树了。
- 设二叉树的先序遍历序列和后序遍历序列正好相反,则该二叉树满足的条件是
A 空或只有一个结点
B 高度等于其结点数
C 任一结点无左孩子
D 任一结点无右孩子
想一想画一画
只有单链的时候才会恰好两个序列反过来,高度等于结点数刚好符合单链的条件
所以选B
好吧这样说很主观 , 不多说: 上给个专业点的解释: 解析
哈夫曼树
哈夫曼树的性质:
-
权重越大的叶子离根越近
-
具有相同带权结点的哈夫曼树不唯一
-
哈夫曼节点的度数为0或2,没有度为1的结点
-
包含个叶子结点的哈夫曼树中共有2n-1个节点包含n颗树的森林要经过n-1此合并才能形成哈夫曼树
-
父节点的权值等于两个子节点权值之和。
有 m 个叶子结点的赫夫曼树所具有的结点总数是( )。
解析:由二叉树的性质得: n0=n2+1,又有n=n0+n2+n1 , 因为哈夫曼树n1=0 ,所以得:n=n0+n0-1=2n0-1,所以答案是:
2m-1
下列选项给出的是从根分别到达两个叶结点路径上的权值序列,能属于同一棵赫夫曼树的是( )。
A.24,10,5 和24,10,7
B. 24,10,5和24,12,7
C. 24,10,10和24,14,11
D. 24,10,5和24,14,6
解析:答案解析
排序
(图片来源网络)
-
折半插入排序算法相比较于直接插入排序算法,只是减少了关键字间的比较次数,而记录的移动次数没有进行优化,所以该算法的时间复杂度仍是
O(n2)
。 -
n 个记录的直接插入排序中,键值的最小比较次数是
n-1
(最好情况下,数组本身有序) -
使用起泡排序对序列进行升序排序,每执行一次交换操作将会减少 1 个逆序对,因此序列 5,4,3,2,1 需要执行的交换次数为(10 )。
4+3+2+1
冒泡排序在最好情况下(基本有序)时间复杂度是O(n) -
设需要对5个不同的记录关键字进行冒泡排序,则至少需要比较___4 ___次,至多需要比较_______10 ______次。
[解析]
:
在冒泡排序中最好的情况是O(n),这意味着两重循环中有一重循环跳过了。 实际上,在数组已经有序的情况下,外循环只执行了一次。
比如 : 1,2,3,4,5按照递增排序,设置一个标志位flag=1 , 设置代码如下:
for(int i=0 ,flag =1 ;i<n&& flag ==1 ;i++{
flag = 0;
for(int j=i;i<n-i-1;j++) {
if(a[j]>a[j+1])
{
flag =1 ; //符合交换条件就把标志位置1
swap(a,i,j) ;
}
}
}
其中1,2,3,4,5 是完全有序的,所以在内循环中始终没有交换过元素, flag就保持为0, 所以外循环也就结束了。所以比较次数就是n-1,4次。
当元素全部逆序排列,此时第一趟循环比较了 n-1 ,第二趟循环为 n-2次… 总比较次数为 n* (n-1) /2 次也就是10次。
而我在学习冒泡排序法的时候从来没有加过这个标志位,所以一上来也有点不明白,后来还是看书看懂了, 所以学习的时候还是多看看书,理论知识打扎实些。
-
冒泡排序算法关键字比较的次数与记录的初始排列次序无关。 (X)
-
快速排序执行一遍之后,已经到位的元素个数是( 1个 )。
-
快速排序每次选择一个基准值,将小的放到左边,大的放到右边,一次排序到位的就是那个基准值。
-
直接选择排序算法在最好情况下的时间复杂度为 O(n)。 (X)
-
如果只想得到1000个元素组成的序列中第5个最小元素之前的部分排序的序列,用( )方法最快。
A.堆排序
B.快速排列
C.简单选择排序
D.直接插入排序
[A
] -
下述二叉树中,( )满足性质:从任一结点出发到根的路径上所经过的结点序列按其关键字有序。
A.二叉排序树
B.堆
C.B-树
D.B+树
E.哈夫曼树
F.AVL树
解析:
二叉排序树只有在中序遍历时才有序,如以3,2,6建树,从2开始为2,6,3 不是有序的。
AVL树是二叉平衡树,也是二叉排序树,同理 哈夫曼树只有叶子节点才是关键字,非叶子结点上根本没有关键字。
堆就是一个从任一结点出发到根的路径上所经过的结点序列按其关键字有序的树状结构。
[B
]
图
图的知识点非常多,这里只做一部分介绍
概念
总览:
- 图、有向图、无向图、网络
- 顶点、边、弧、权、度、出度、入度
- 完全图、有向完全图、稀疏图、稠密图
- 路径、简单路径、回路/环、简单回路/简单环
- 子图、连通图、连通分量、强连通图、强连通分量
- 生成树、有向树、生成森林
①、连通图: 无向图中,如果任意两个顶点之间都能够连通,则称此无向图为连通图
②、强连通图: 有向图中,若满足VI到Vj ,Vj到Vi连通, 也就是至少有一条通路,则称其为强连通图。
③、 完全图:一个无向图中,每两个顶点存在边,则称其无向完全图
❓完全图有多少条边?
设有n个顶点,每个点与其它n-1个点相连,则共有n*(n-1),但是每天边都被计算了两次,所以要再除以2
即n个顶点,n(n-1)/2条边
④、有向完全图
如果在一个有向图中,每两个顶点之间都存在方向相反的两条边,则称其为有向完全图。
- G是一个非连通无向图,共有28条边,则该图至少有( )个顶点。
非连通的,要使顶点最少,所以是一个完全图:由公式:n个顶点,有n*(n-1)/2 条边。 28=7*8/2 ,加一个顶点: 答案: 有9个顶点
- 已知无向图 G 含有 16 条边,其中度为 4 的顶点个数为 3,度为 3 的顶点个数为 4,其他顶点的度均小于 3 ,则图 G 所含的顶点个数至少是()。
由图的性质: 总度数=边的两倍。总共有32度。已知7个点。剩余8度,4个点每一个都是2度。至少7+4=11个点。
- 用有向无环图描述表达式 ( A + B ) * ( ( A + B ) / A ) ,至少需要顶点的数目为( )。
考点: 将二叉树转换成有向无环图
答案解析
查找
ASL(Average Search Length):平均查找长度
哈希表:
ASL_成功 = 每个元素被访问(查找)的次数
ASL_失败 = 每个地址被访问(查找)的次数
不多说,上题:
- 设散列表的长度为8,散列函数H(k)=k % 7,用线性探测法解决冲突,则根据一组初始关键字序列(8,15,16,22,30,32)构造出的散列表的平均查找长度是____。
H(8)=1, H(15)=1 , H(16)=2, H(22)=1…依次计算下去。
找8时,查找次数为1
15: 查找次数为1+1 =2 (哈希冲突)
16: 查找次数为1+1=2
依次类推;
所以 答案(1+2+2+4+4+3)/ 6 = 8/3
- 哈希表的平均查找长度(ASL)和哈希函数,处理冲突的方法,装填因子直接相关(√)
装填因子 a
是哈希表中存入数据元素个数n
与哈希表长m
的比值 ,即 a = n/m
.
a越大,说明存入的元素越多,冲突可能性越大,a越小,哈希冲突越小。 通常将 a控制在 0.6~0.9 间。
二叉排序树
对于有n的结点的二叉排序树来说,每一个数据元素的查找概率相等,则二叉排序数平均查找长度为为结点在二叉树的深度函数。 结点在树中越深,比较次数就越多。
平均长度为:O(lbn)
最坏情况下: 即为单分支退化树时,查找长度为: O(n)
查找成功的平均查找长度为:∑(本层高度*本层元素个数)/节点总数
查找不成功的平均查找长度:∑(本层高度*本层补上的叶子个数)/补上的叶子总数
折半查找
查找过程可以用二叉树来描述,这棵树称为判定树。
所以折半查找的 ASL 可以利用二叉判定树计算:
(图片均来源网络 ,侵删。)
如图,如果要找64,分别要和 56, 80,64 比较, 比较次数为3 .
可以发现: 比较次数恰好是该关键字所在判定树中的层次。
判定树的成功时的平均查找长度就是计算每一个结点的比较(查找)次数之和,再除以有序表的长度。
如果查找失败,即要走一条从根节点到一个空指针的路径, 平均查找长度即为查找每一个空指针(也可以理解为外结点)的比较次数之和除以外结点的个数。
- 有个长度为12的无重复有序表,按折半查找法进行查找,在表内各元素等概率情况下,查找成功所需的平均比较的次数为()
将其判定树画出来然后计算: 1 * 1+2 * 2+ 4 * 3 * 5 * 4=37
37/12
- 设一组有序的记录关键字序列为(13,18,24,35,47,50,62,83,90),查找方法用二分查找,计算出查找成功时的平均查找长度。
同理:画树计算:
(1* 1 + 2* 2+ 3* 4 + 4*2 )/9 =25/9 答案: 25/9