这星期的算法课上学到了这两个的算法思想,感觉自己听懂了,下来自己编代码的时候却无从下手,哈夫曼编码本来想用python的字典来写,可是字典无法嵌套,然后想着用数组写,数组虽然能嵌套,可是解嵌套又写不了。。。没办法上网搜了别人写的,用了类,emmm,牛批。
哈夫曼编码就是想在表示字符时,频率高的字符用少点位数表示,频率低的用多点,这样可以减小平均编码位数,从而减小总的编码位数。
哈夫曼编码的思想大致是将所有的字符分别看作节点,在这些节点里选取两个频率最小的两个,组成一个节点(同时这两个节点就不能单独存在了,即“消失了”或者说“合体了”),最小的是左节点,次小的是右节点,然后把这个节点加入之前那一堆节点中,然后重复这个步骤使只剩下一个节点(即成树,我的理解就是嵌套完成)。获取字符编码(我理解就是解嵌套)时,从树顶开始,左节点标0(或1),右节点标1(或0)。
代码:
class node:
def __init__(self, name, freq):
self.name = name
self.left = None
self.right = None
self.father = None
self.freq = freq
def is_left(self):
return self.father.left == self
def create_node(shuju):
data = []
for i in shuju:
data.append([i, shuju[i]])
return [node(str, name) for str, name in data]
def HFM(Node):
Node_1 = Node[:]
while len(Node_1) > 1:
Node_1.sort(key=lambda x: x.freq)
node_left = Node_1.pop(0)
node_right = Node_1.pop(0)
node_father = node(None, node_left.freq + node_right.freq)
node_father.left = node_left
node_father.right = node_right
node_left.father = node_father
node_right.father = node_father
Node_1.append(node_father)
Node_1[0].father = None
return Node_1[0]
# def BM(Node, name):
# s = ''
# for i in Node:
# if i.name == name:
# while i.father != None:
# if i.is_left():
# s = '0' + s
# else:
# s = '1' + s
# i = i.father
# return s
def BMS(Node):
codes = {}
for i in Node:
name = i.name
codes[name] = ''
while i.father != None:
if i.is_left():
codes[name] = '0' + codes[name]
else:
codes[name] = '1' + codes[name]
i = i.father
return codes
def main():
shuju = {'A': 0.4, 'B': 0.1, 'C': 0.2, 'D': 0.15, '_': 0.15}
Node = create_node(shuju)
HFM(Node)
s = BMS(Node)
print(s)
if __name__ == '__main__':
main()
然后是那个有向图源点到某点的最短路径,本来我觉得这个应该很好写,但是也是感觉编码无从下手,想了半天先写哈夫曼去了,哈夫曼写完了我感觉这个用类应该好写点,然后也用类写了。
这个问题就是有一堆点,知道某点到某点距离和方向,问从某一点(源点)出发,到某一点(终点)的路程最短走法。
算法思想是贪心算法,每次都选取最短的路径,从源点开始,记录所有点(只能通过源点)此时到源点的最小距离,选出其中路径最短的那个点,然后记录所有点(只通过源点和这个点)能到达的点及此时到源点的最小距离,选出其中路径最短的那个点,然后记录所有点(只通过这三个点)此时到源点的最小距离,重复这个步骤直至遍历所有点。
正式点说就是记录s集合和t-s集合,s是已经遍历的点,t是指所有点。
```python
```python
```python
```python
class Top:
def __init__(self, name):
self.name = name
self.father = None
self.min_d = float('inf')
def create_tree(shuju):
data = []
set1 = set()
for i in shuju:
set1.add(i[0])
set1.add(i[1])
for j in set1:
data.append(j)
return [Top(name) for name in data]
def zuiduan(yuandian, tree, shuju):
tree_1 = tree.copy()
for i in tree_1:
if i.name == yuandian:
i.min_d = 0
while len(tree_1) != 0:
tree_1.sort(key=lambda x: x.min_d)
top = tree_1.pop(0)
for j in shuju:
if j[0] == top.name:
for k in tree:
if k.name == j[1]:
if k.min_d > top.min_d + shuju[j]:
k.father = top
k.min_d = top.min_d + shuju[j]
return tree
def lujing(tree, zhongdian):
lu = ''
for i in tree:
if i.name == zhongdian:
while i.father != None:
lu = '从%s走到%s,' % (i.father.name, i.name) + lu
i = i.father
break
lu = lu[:-1]
print(lu)
def main():
# shuju = {(1, 2): 10, (1, 4): 30, (1, 5): 100, (2, 3): 50, (3, 5): 10, (4, 3): 20,
# (4, 5): 60}
shuju = {(1, 2): 1, (1, 3): 2, (2, 4): 3, (3, 4): 1}
tree = create_tree(shuju)
# zuiduan(1, tree, shuju)
# for i in tree:
# print(i.name)
# print(i.min_d)
tree_min = zuiduan(1, tree, shuju)
lujing(tree_min, 4)
if __name__ == '__main__':
main()