写一个霍夫曼数
第十一章 14题
霍夫曼数:
构建哈夫曼树:
https://jingyan.baidu.com/article/a501d80c16dfa0ec620f5e70.html
https://blog.csdn.net/lzq20115395/article/details/78906863
https://blog.csdn.net/luolinll1212/article/details/81389315
// An highlighted block
#节点类
class Node:
def __init__(self,name=None,value=None):
self._name = name
self._value = value
self._left = None
self._right = None
#霍夫曼树
class HuffmanTree:
#根据Huffman树的思想:以叶子节点为基础,根据value排序,反向创建Huffman树
def __init__(self,char_weights):
self.a = [Node(key,value) for key,value in dict.items()]
while len(self.a)!=1:
self.a.sort(key=lambda node: node._value,reverse=True)
c = Node(value=(self.a[-1]._value+self.a[-2]._value))
c._left = self.a.pop(-1)
c._right = self.a.pop(-1)
self.a.append(c)
self.root=self.a[0]
self.b = list(range(20))
#递归的思想生成编码
def pre(self,tree,length):
node = tree
if (not node):
return
elif node._name:
str_num = ""
for i in range(length):
str_num+=str(self.b[i])+""
print(node._name+'编码为:',str_num)
return
self.b[length]=0
self.pre(node._left,length+1)
self.b[length] = 1
self.pre(node._right,length+1)
#生成霍夫曼编码
def get_code(self):
self.pre(self.root,0)
if __name__ == '__main__':
dict = {"a":9,"b":12,"c":6,"d":3,"e":5,"f":15}
tree = HuffmanTree(dict)
tree.get_code()
----2020/3/15
----栈和队列都是线性表,只是在插入和删除时受到了一些限制。
正确答案: A
T
F
解析:栈和队列都是特殊的线性表,对插入删除有限制。
栈 先进后出 在表尾进行插入和删除
队列 先进先出 在表尾进行插入,表头进行删除
----题目来源于王道论坛
设栈S和队列Q的初始状态均为空,元素a,b,c,d,e,f,g依次进入栈S。若每个元素出栈后立即进入队列Q,且7个元素出队的顺序是b,d,c,f,e,a,g,则栈S的容量至少是()。
正确答案: C
1
2
3
4
解析:
----下列叙述中正确的是( )。
正确答案: B
循环队列是队列的一种链式存储结构
循环队列是队列的一种顺序存储结构
循环队列是非线性结构
循环队列是一种逻辑结构
解析:循环队列是顺序存储的线性结构
数据结构=逻辑结构(线性、非线性)+存储结构(顺序、链式、索引、散列)
-
逻辑结构:数据元素间抽象化的相互关系
-
存储结构:(物理结构),在计算机存储器中的存储形式
----在循环队列中,若 front 与 rear 分别表示对头元素和队尾元素的位置,则判断循环队列空的条件是 。
正确答案: A
frontrear+1
rearfront+1
frontrear
front0
解析:关于循环队列的一些计算问题:
front为队头、rear为队尾、maxSize为队列的总容量、m为队列中元素的个数:
队空:front = rear
队满:(rear + 1) % maxSize = front
进队:front = (front + 1) % maxSize
出队:rear = (rear + 1) % maxSize
队列中元素的个数 m = (rear - front + maxSize) % maxSize
----便于插入和删除的容器是()
正确答案: A C D
list
vector
map
set
解析:
1:vector 底层数据结构为数组,支持快速随机访问
2:list 底层数据结构为双向链表,支持快速增删
3:map、set都是STL关联容器,支持快速增删
----2020/3/16
----设循环队列的容量为50(序号从0到49),现经过一系列的入队和出队运算后,有 front=16,rear=5(rear指向队尾元素的后一位置),当前循环队列中元素个数为( )
正确答案: B
11
39
40
12
解析:
||______||
0 5 16 49
rear(队尾下一个位置) front(队头)
应该是49-16+5-1-0+1=39
----一个队列的进队顺序是1,2,…n,若进队和出队可以交替进行,则出队顺序可能是()
正确答案: A
1,2,…,n
1,2,4,3,5,6,…,n
n,n-1,…,1
以上均有可能
解析:队列进出的顺序不会因为进出的交替进行而有所改变。
----STL中的优先队列是采用什么数据结构来实现的?()
正确答案: A
堆
队列
栈
图
解析:priority_queue 底层是堆
----已知输入序列为abcd经过输出受限的双向队列后能得到的输出序列有()
正确答案: B D
dacb
cadb
dbca
bdac
解析:出队受限的队列(单方向出队),入队可以两端入队,并且只限制进队的顺序,不限制是否全部进入才出队。
----在用单链表表示的链式队列中,队头在链表的链尾位置。( )
正确答案: B
正确
错误
解析:队列的链式存储结构成为链队列,它是限制仅在表头删除和表尾插入的单链表,队头在链头位置。
----执行()操作时,需要使用队列作为辅助存储空间。
正确答案: B
查找哈希(hash)表
广度优先搜索图
先序(根)遍历二叉树
深度优先搜索图
解析:BFS需要队列的辅助,深度优先需要栈的辅助。
辅助储存空间
图的拓扑排序,深度优先 关键路径算法用的栈辅助
树的层次遍历 图的广度优先遍历用的队列辅助
----有一个用数组C[1…m]表示的环形队列,m为数组的长度。假设f为队头元素在数组中的位置,r为队尾元素的后一位置(按顺时针方向)。若队列非空,则计算队列中元素个数的公式应为?
正确答案: A
(m+r-f)mod m
r-f
(m-r+f) mod m
(m-r-f) mod m
(r-f) mod m
需要判断边界
解析:分情况讨论:
- 若f<r<=m, 则有r-f <m,即队尾没有超出边界,则为r-f
- 若r<f<=m, r-f < 0, 即队尾超出边界m,那么应为m+r -f
综合两种情况,得到答案 (m+r-f) mod m
记住两个公式:队列中,队列满的条件是:(rear+1)%QueueSize=front;
队列长度公式是:(rear-front+QueueSize)%QueueSize。
----2020/4/24
----需要频繁的插入删除操作使用什么结构比较合适?
正确答案: C
数组
队列
链表
栈
解析:A,数组是连续地址的,插入和删除都需要移动大量元素,不适合插入删除操作
B,队列适合一端插入另一端删除的情况
C,链表适合插入和删除,不需要移动元素
D, 栈适合在同一端插入和删除的操作
----数组Q[n]用来表示一个循环队列,f为当前队列头元素的前一位置,r为队尾元素的位置,假定队列中元素的个数小于n,计算队列中元素的公式为()。
正确答案: D
r-f
(n+f-r)% n
n+r-f
(n+r-f)% n
解析:
----用俩个栈模拟实现一个队列,如果栈的容量分别是O和P(O>P),那么模拟实现的队列最大容量是多少?
正确答案: C
O+P
2O+1
2P+1
2O-1
解析:栈,先进后出;队列,先进先出。用O和P这两个栈实现先进先出就可以了。
----线性表就是顺序存储的表()
正确答案: B
对
错
解析:线性结构与非线性结构,主要看元素之间的关系,如果是一对一的关系则是线性表,如果不是一对一的关系则是非线性表。
----以下哪一个不是队列的基本运算?( )
正确答案: A
在队列第i个元素之后插入一个元素
从队头删除一个元素
断一个队列是否为空
读取队头元素的值
解析:
----用链接方式存储的队列,在进行删除运算时( )。
正确答案: D
仅修改头指针
仅修改尾指针
头、尾指针都要修改
头、尾指针可能都要修改
解析:在有头结点的链队列的出队操作中,一般只需修改队头指针,但当原队列中只有一个结点时,该结点既是队头也是队尾,故删去此结点时亦需修改队尾指针,使其指向头结点,且删去此结点后队列变空。
----已知循环队列存储在一维数组A[0…n-1]中,且队列非空时 front 和 rear 分别指向队头和队尾元素。若初始时队列为空,且要求第 1 个进入队列的元素存储在 A[0]处,则初始时 front和 rear 的值分别是( )。
正确答案: B
0, 0
0, n-1
n-1, 0
n-1, n-1
解析:插入时,队头指针不变,队尾指针后移一位。该题约定队列非空时 front 和 rear 分别指向队头和队尾元素,即插入第一个元素在下标为0的位置后,队头队尾指针皆指向A[0],此时可以反推出插入前,队头指针仍旧指向下标0,而队尾指针应指向前一位,也就是下标n-1的位置。注意,这道题的约定与大多数题约定队列为空时front=rear=0是不一样的约定,都是根据题意解题。
----有一个虚拟存储系统,若进程在内存中占3页(开始时内存为空),若采用先进先出(FIFO)页面淘汰算法,当执行如下访问页号序列后1,2,3,4,5, 1,2,5,1,2,3,4,5,会发生多少缺页?
正确答案: D
7
8
9
10
解析:FIFO,发生缺页时的调入顺序即为淘汰顺序
1、访问1,缺页,调入1,内存中为 1, ,;
2、访问2,缺页,调入2,内存中为 1,2,;
3、 访问3,缺页,调入3,内存中为 1,2,3;
4、 访问4,缺页,调入4,淘汰1,内存中为 4,2,3;
5、 访问5,缺页,调入5,淘汰2,内存中为 4,5,3;
6、 访问1,缺页,调入1,淘汰3,内存中为 4,5,1;
7、 访问2,缺页,调入2,淘汰4,内存中为 2,5,1;
8、 访问5,不缺页,内存中为 2,5,1;
9、 访问1,不缺页,内存中为 2,5,1;
10、 访问2,不缺页,内存中为 2,5,1;
11、访问3,缺页,调入3,淘汰5,内存中为 2,3,1;
12、访问4,缺页,调入4,淘汰1,内存中为 2,3,4;
13、访问5,缺页,调入5,淘汰2,内存中为 5,3,4;
----某带链的队列初始状态为 front=rear=NULL 。经过一系列正常的入队与退队操作后, front=rear=10 。该队列中的元素个数为( )
正确答案: A
1
0
1或0
不确定
解析:
----下列哪种算法使用了队列作为辅助存储结构()。
正确答案: B
二叉树的先根序遍历算法
二叉树的层次遍历算法
图的深度优先遍历算法
图的拓扑排序算法
解析:图的拓扑排序 深度优先 关键路径算法用的辅助数据结构是栈
树的层序遍历 图的广度优先遍历用的数据结构是队列
----将新元素插入到链式队列中时,新元素只能插入到( )
正确答案: B
链头
链尾
链中
第i个位置,i大于等于1,大于等于表长加1
解析:队列只可以从队尾插入,链式存储是存储结构
----2020/5/9
----设顺序循环队列Q[0,M-1]的头指针和尾指针分别为F和R,头指针F总是指向队头元素的前一位,尾指针R总是指向队尾元素的当前位置,则该循环队列职工的元素个数为( )?
正确答案: B
(F-R)%M
(R-F+M)%M
(F-R+M)%M
R-F-1
解析:
----在链队列中,即使不设置尾指针也能进行入队操作()
正确答案: A
对
错
解析: 若使用不设置尾指针的链表作为链队列的存储结构,在进行入队操作的时候需要遍历整个链队列至队尾,然后在进行插入。这当然是可行的,只是效率有所下降。 如果只使用一个指针又要保持效率的话,可以使用只带尾指针的循环单链表作为存储结构,这样出队和入队的开销都是O(1)。
----下面哪种数据结构最适合创建一个优先级队列()
正确答案: A
堆
双向链表
单向链表
栈
解析:一般用堆来实现,就是具有优先级的队列。在一堆数中能够确定那个最大,最大的优先服务。
----线性表的顺序存储方式具有哪些优点()
正确答案: A B C
可以用结点的物理次序反映结点之间的逻辑关系
存储密度高,节省存储空间
在结点等长时可以随机存取
插入和删除比较灵活
解析:因此D不是顺序存储的优点,而是链接存储的优点。
栈和队列的共同点是( )。
正确答案: C
都是先进后出
都是后进先出
只允许在端点处插入和删除元素
都是先进先出
解析:栈是先进后出,后进先出;队列是先进先出,后进后出
栈只允许在栈顶进入或弹出;队列则是在队头弹出,队尾进入,即:均只能在端点进行操作。
----若用一个大小为 6 的数组来实现循环队列,且当 rear 和 front 的值分别为 0 和 3 。当从队列中删除一个元素,再加入两个元素后, rear 和 front 的值分别为 。
正确答案: B
1和5
2和4
4和2
5和1
解析:
1、队列添加元素是在对尾,删除元素是在对头;
2、添加元素,尾指针rear+1;删除元素,头指针front+1;
3、本题中,删除一个元素,front+1,也就是3+1=4;添加2个元素,rear+2,也就是0+2=2;
4、选 B’
----优先级队列和有序数组的一个区别是()
正确答案: A
最低优先级别的数据项不能从数组中轻易的提取出来,而在优先级队列中可以。
数组必须是有序的,而优先级队列不需要。
最高优先级的数据项可以很容易地从优先级队列中提取出来,而有序数组不行。
其他三个选项都是。
解析:A.最大堆你可以想象成一颗二叉树,堆顶元素一定是最大值,然后它的每一棵子树也都是最大堆。优先队列的默认实现是最大堆,但是里面有个参数可以设置,设置之后就是最小堆。所以A是对的,最低优先级可以提取
B.数组和优先队列都不是有序的
C.有序数组是一种特殊的数组,里面的元素,按一定的顺序排列。有序数组可以直接提取最高优先级的元素