20211018 数据结构和算法

如何系统地学习数据结构与算法? - 知乎

深度学习 遗产算法

我想让机器人Bob画出我的梦中情人(最优解)。Bob当然不知道我梦中情人长啥样。

Bob很无奈,只能一张张试。先画一张,问我像不像?我说不像,Bob就重新画一张。直到我觉得像。

然而Bob又不会画画,只会填格子。于是Bob准备了一张1000*1000的格子纸,每个格子可以填黑色或者白色。那么总共有2^1000000种画法。如果我能坚持到宇宙毁灭N次,那可以每张都看,然后找到那个最像的。显然我没这个耐心。

于是我只让Bob画10万张,画不出来我就砸了它。

Bob很紧张,开始想办法,终于想到了遗传算法

第一轮,Bob随机画了1万张(初始种群)。这1万张里面,肯定各种乱七八糟,有像星空的,像猪的,像石头的,等等。然后Bob让我挑最像的。妈蛋,我强忍怒火,挑出来一堆猪、猴、狗,好歹是哺乳动物。

Bob拿着我挑的“猪猴狗们”,如获至宝,开始第二轮,将这些画各种交叉变异一下。比如把一幅画的耳朵跟另一幅的鼻子换一下,或者再随机改个眼睛。然后又生成了1万张图让我挑。我挑出来一堆猴子猩猩,好歹是灵长类动物。

如此反复好多轮后,挑出来的开始像人了,虽然有男人、女人、小孩。
慢慢地,开始有美女了。再慢慢地,就越来越像了。

在画了10万张图后,终于找到一张还不错的。虽然不是梦中情人,但也很不错呐(次优解)。

这就是遗传算法

数据结构

一、线性表(数组、栈、队列、链表)

1、实现栈(动态数组(列表)实现太多,内存占用大)  先进后出

from collections import deque
stack = deque()
stack.append('hello')
stack.append('world')
print(stack.pop())
print(stack.pop())

2、队列   先进先出

from Queue import Queue,LifoQueue,PriorityQueue
#先进先出队列
q=Queue(maxsize=5)
#后进先出队列
lq=LifoQueue(maxsize=6)
#优先级队列
pq=PriorityQueue(maxsize=5)
 
for i in range(5):
    q.put(i)
    lq.put(i)
    pq.put(i)

3、链表(单向、双向、循环)

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。

链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储元素的数据,另一个就是指向下一个节点的指针

链表适合插入

每个节点包含数据和上下指针

总结:

数组的特点是:寻址容易,插入和删除困难;

而链表的特点是:寻址困难,插入和删除容易。

数组是顺序的,其载内存里的存储方式也是顺序的,链表是通过指针连接起来的,而不需要顺序排列!

二、散列表(哈希表)

哈希表hashtable(key,value) 就是把Key通过一个固定的算法函数既所谓的哈希函数转换成一个整型数字,然后就将该数字对数组长度进行取余,取余结果就当作数组的下标,将value存储在以该数字为下标的数组空间里。

那么我们能不能综合两者的特性,做出一种寻址容易,插入删除也容易的数据结构?答案是肯定的,这就是我们要提起的哈希表,哈希表有多种不同的实现方法,我接下来解释的是最常用的一种方法——拉链法,我们可以理解为“链表的数组”,如图:


左边很明显是个数组,数组的每个成员包括一个指针,指向一个链表的头,当然这个链表可能为空,也可能元素很多。我们根据元素的一些特征把元素分配到不同的链表中去,也是根据这些特征,找到正确的链表,再从链表中找出这个元素。

哈希是一种加密算法

1.输入域无穷大

2.输出域是有穷尽的

3.输入参数相同,返回哈希值不变(不是随机函数)

4.输入不同,哈希值亦可能相同,哈希碰撞

应用

1、哈希算法在密码学中的应用

2、哈希算法进行文件校验


三、树

1、二叉树(二叉查找树、平衡二叉树、平衡二叉查找树(红黑树、AVL树)、完全二叉树)

二叉查找树:可以深层,左小于右

平衡二叉树:树的左右子树的高度差不超过1的数,空树也是平衡二叉树的一种。

红黑树:

R-B Tree,全称是Red-Black Tree,又称为“红黑树”,它一种特殊的二叉查找树。红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black)。

红黑树的特性:
(1)每个节点或者是黑色,或者是红色。
(2)根节点是黑色。
(3)每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!]
(4)如果一个节点是红色的,则它的子节点必须是黑色的。
(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。

注意
(01) 特性(3)中的叶子节点,是只为空(NIL或null)的节点。
(02) 特性(5),确保没有一条路径会比其他路径长出俩倍。因而,红黑树是相对是接近平衡的二叉树。

红黑树示意图如下:

完全二叉树: 只有最下面的两层结点度小于2,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树

2、多路查找树(B树、B+树)

3、堆(小顶堆、大顶堆、二项堆、优先队列、斐波那契堆)

4、图(图的存储、关键路径、最小生成树、最短路径、拓扑排序)

算法

1、基本算法思想(动态规划、贪心算法、回溯算法、分治算法、枚举算法)

2、复杂度分析(空间、时间)

3、搜索(深度优先、广度优先)

4、查找(二分查找、散列表查找、树结构查找)

5、字符串匹配(暴力匹配、BM、KMP、Trie)

6、排序

7、其他(并查集、迪杰斯特拉、拓扑)

四、二叉树 求深度

class Node:
    def __init__(self, value=None, left=None, right=None):
        self.value = value
        self.left = left
        self.right = right


def tree_depth(tree):
    if tree is None:
        return 0
    left_depth = tree_depth(tree.left)
    right_depth = tree_depth(tree.right)
    return left_depth + 1 if left_depth > right_depth else right_depth + 1


trr = Node('D', left=Node('B', Node('A'), Node('C')), right=Node('E', right=Node('G', Node('F'))))
print(trr)
a = tree_depth(trr)
print(a)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值