目前正在攻读考试,在阅读一些笔记时,我有几个问题。
我知道二进制搜索树的高度是Log(n)。这是否意味着深度也是Log(n)?
具有n个节点的完整二叉树中节点的最大深度是多少?这与第一个问题有关;如果二叉树的高度是Log(n),最大深度是否也是Log(n)?
我知道在二叉搜索树中搜索节点的时间复杂度是O(Log(n)),我理解。但是,我读到最坏的情况时间复杂度是O(N)。在什么情况下需要花费O(N)时间来找到元素?
这是优先考虑的问题/堆问题。在我的讲义中,它说了以下声明:
如果我们使用数组作为优先级队列,则入队需要O(1),而出队则需要O(n)。在排序数组中,en-queue采用O(N),de-queue采用O(1)。
我很难理解这一点。任何人都可以解释一下吗?
对于所有问题,我们非常需要澄清其中一些主题。
答案 0 :(得分:0)
二叉树的高度和深度是同义词 - 或多或少。 height是从根到叶的任何路径的最大深度。但是,当你遍历一棵树时,你就有了当前深度的概念。根节点的深度为0,其子节点的深度为1,其孙子深度为2.如果我们停在此处,树的高度为3,但最大深度[我们访问过]为2.否则,它们经常在谈论时互换这整棵树。
在我们解决您的更多问题之前,请务必注意二叉树有各种各样的风格。平衡或不平衡。使用完美平衡的树,除了最大高度的节点之外的所有节点都将使其左/右链接为非空。例如,在树中有n个节点,设n = 1024.完全平衡高度为log2(n),即10(例如1024 == 2 ^ 10)。
当您搜索完美平衡的树时,搜索是 O(log2(n)),因为从根节点开始,您选择向左或向右,并且每次执行时,你消除了1/2的节点。在这样一个有1024个元素的树中,深度为10,你可以做出10个这样的左/右决定。
当您添加新节点时,大多数树算法将动态地重新平衡树(例如AVL或RB(红黑))树。所以,你或多或少地得到一棵完美平衡的树。
但是......
让我们考虑一个非常糟糕的算法。添加新节点时,它只会将其附加到具有最大深度的子节点上的左侧链接[或新节点成为新根节点]。这个想法是快速追加,“我们将在以后重新平衡”。
如果我们搜索这个“坏”树,如果我们添加了n个节点,那么该树看起来像是使用父链接和左链接的双向链表[记住所有正确的链接都是NULL]。这是线性时间搜索或O(n)。
我们故意这样做,但它仍然可以通过一些树算法和/或数据组合来实现。也就是说,数据是自然放置在左侧链接上的,因为根据算法的放置函数放置它是正确的。
优先级队列就像常规队列,但每个数据都有一个与之关联的优先级编号。
在普通队列中,您只需按下/追加到最后。当你出队时,你从前面移动/弹出。你从不需要在中间插入任何东西。因此,入队和出队都是O(1)操作。
O(n)来自这样一个事实:如果你必须插入一个数组的中间,你必须“分水”为你想要插入的元素腾出空间。例如,如果需要在第一个元素[array [0]]之后插入,则将新元素放在数组[1]中,但首先必须将数组[1]移动到数组[2], array [2]到array [3],...对于n的数组,这是O(n)的努力。
从数组中删除元素时,它是相似的,但相反。如果你想删除数组[1],你可以抓住它,然后你必须通过数组[1] =数组[2],数组[2] =数组[3],...来移除左边的“间隙”。再一次,O(n)操作。
在排序数组中,您只需弹出结尾。这是你想要的。因此O(1)。要添加元素,请将其插入正确的位置。如果您的数组是1,2,3,7,9,12,17并且您想要添加6,这是数组[4]的新值,您必须将7,9,12,17移开上方。
优先级队列只是附加到数组,因此O(1)。但是为了找到要出列的正确元素,你要扫描数组数组[0],数组[1],......记住给定优先级的第一个元素位置,如果找到更好的优先级,你会记住这一点。当你到达终点时,你知道你需要哪个元素,比如它是j。现在你必须从数组中删除j,以及如上所述的O(n)操作。
它比所有这些稍微复杂,但不是两个。