氧气 电路_编程中的树木简介:高效编码的氧气

氧气 电路

by Tiago Antunes

由Tiago Antunes

编程中的树木简介:高效编码的氧气 (An introduction to trees in programming: the oxygen of efficient coding)

Many times you wish to save information in your program and access it many times. And you’ll often store it in a very simple data structure: an array. And it often works really well! But sometimes it just takes a lot of time to finish.

很多时候,您希望将信息保存在程序中并多次访问。 而且,您通常会将其存储在一个非常简单的数据结构中:数组。 而且通常效果很好! 但是有时它只需要花费很多时间就可以完成。

And so, to optimize this kind of program, many smart people developed some weird things that we call data structures. Today I’ll be addressing some basics about this topic, and I’ll discuss one specific structure that is often asked about during coding interviews and makes everyone crazy: Trees.

因此,为了优化这种程序,许多聪明的人开发了一些奇怪的东西,我们称之为数据结构 。 今天,我将讨论有关该主题的一些基础知识,并且我将讨论一种在编写代码采访时经常被问到并使每个人都抓狂的特定结构:树。

I won’t be diving much into the code, only into the theory of how everything works. There are millions of code samples online, so just take a look at one after you understand how trees work!

我不会深入研究代码,而只会深入研究一切工作原理。 在线有数百万个代码示例,因此在了解树的工作原理之后,只需看一看即可!

那么什么是数据结构呢? (So what really is a data structure?)

According to Wikipedia:

根据维基百科:

“ a data structure is a data organization and storage format that enables efficient access and modification”

数据结构是一种能够有效访问和修改的数据组织和存储格式”

This basically means that it’s nothing more than code written to create a complex way to store data. There are a lot of data structures that you can implement, and each one has a specific task. They can go from really simple ones — like linked lists — to really complex structures — like graphs.

基本上,这意味着只不过是编写用于创建存储数据的复杂方式的代码而已。 您可以实现许多数据结构,每个结构都有一个特定的任务。 它们可以从非常简单的对象(例如链表)到非常复杂的结构(例如图)。

Trees are complex enough to be really fast at what they do, but simple enough that that they’re understandable. And one thing they’re really good at is finding values with minimum memory usage.

树木足够复杂,可以真正快速地完成它们的工作,但又足够简单,可以理解。 他们真正擅长的一件事是找到具有最小内存使用量的值。

但是,您如何衡量数据结构的效率呢? (But how do you measure how efficient a data structure really is?)

Have you ever seen some strange notation people use online like O(n)? That’s called Big O Notation, and it’s the standard way to evaluate the performance of structures and algorithms. The big O that we use is the representation of the worst-case scenario: having something that is O(n) (with n being the number of elements inside) means that in the worst case it takes time n, which is really good.

您是否见过人们在网上使用一些奇怪的符号,例如O(n)? 这就是所谓的Big O表示法,它是评估结构和算法性能的标准方法。 我们使用的大O代表最坏情况的表现:拥有O(n)(其中n是内部元素的数量)的意思是在最坏情况下需要时间n ,这确实很好。

Inside the parenthesis, we wrote n which is the equivalent of writing the expression y = x → . It scales proportionally. But sometimes we have different expressions:

在括号内,我们写了n ,它等于写表达式y = x → 。 它按比例缩放。 但是有时候我们有不同的表达方式:

  • O(1)

    O(1)
  • O(log(n))

    O(log(n))
  • O(n)

    上)
  • O(n²)

    O(n²)
  • O(n³)

    O(n³)
  • O(n!)

    上!)
  • O(e^n)

    O(e ^ n)

The lower the result of a function, the more efficient a structure is. There are multiple types of trees. We will be talking about BST (Binary-Search Trees) and AVL Trees (Auto balanced trees) which have different properties:

函数的结果越低,结构越有效。 有多种类型的树。 我们将讨论具有不同属性的BST(二进制搜索树)和AVL树(自动平衡树):

好的,您谈到了所有这些怪异的表示法...那么树如何工作? (Ok you talked about all this weird notation…so how do trees work?)

The name tree comes from its real representation: it has a root, leaves and branches, and is often represented like this:

名称树来自其真实的表示形式:它有一个根,叶子和树枝,并且通常这样表示:

There are a few denominations that we use, namely parent and child, which have a unique relationship. If x is parent of y then y is child of x. In this image, 2 is parent of 5, then 5 is child of 2. Each node — each position with a value — can only have 1 parent and 2 children.

我们使用几种教派,即父母和子女,它们有着独特的关系。 如果xy的父级,则yx的子级。 在此图中,2是5的父级,然后5是2的子级。每个节点(每个位置都有一个值)只能有1个父级和2个子级。

But besides all this, there isn’t a pattern that is followed so this tree isn’t really that useful… So we should add a few more rules to make a good data structure.

但是除此之外,没有遵循的模式,所以这棵树并不是真正有用的……因此,我们应该添加一些规则,以建立良好的数据结构。

二叉搜索树 (Binary search trees)

That’s when Binary-Search Trees come in! Instead of just randomly placing child nodes, they follow a specific order:

那就是二进制搜索树出现的时候! 它们不仅遵循随机顺序放置子节点,而且遵循特定的顺序:

  • If there are no nodes, then the first value that is entered becomes the root of the tree.

    如果没有节点,则输入的第一个值将成为树的

  • If there are nodes, then the insertion takes the following steps: starting at the root, if the value you’re entering is smaller than the current node, go through the left branch, else go through the right one. If you’re in an empty place, then that’s where your value belongs!

    如果有节点,则插入将执行以下步骤:从根开始,如果输入的值小于当前节点,则通过左分支,否则通过右分支。 如果您在一个空旷的地方,那么这就是您的价值所在!

This might feel a little confusing at the beginning, but let’s write some pseudo code to simplify it:

刚开始时可能会感到有些困惑,但是让我们编写一些伪代码来简化它:

//This code won't compile in any language (that I know of) and only serves to demonstrate how the code would look like
def insert(Node n, int v) {    if n is NULL:        return createNode(v)    else if n.value < v:        n.right = insert(n.right, v)    else:        n.left = insert(n.left, v)    return n}

Now what’s happening here? First we check if the place where we are now is empty. If it is, we create a node in that place with the function createNode. If it’s not empty, then we must see where we should place our node.

现在这里发生了什么? 首先,我们检查我们现在所处的地方是否为空。 如果是的话,我们在该位置使用createNode函数创建一个节点。 如果不为空,那么我们必须查看将节点放置在何处。

This demo shows how it works:

该演示演示了它是如何工作的:

This way we can search for any value in the tree without having to go through all the nodes. Great!

这样,我们可以搜索树中的任何值,而不必遍历所有节点。 大!

But it doesn’t always go as well as in the gif above. What if we get something like this?

但这并不总是像上面的gif一样好。 如果我们得到这样的东西怎么办?

In this case, the behavior of the tree makes you go through all of the nodes. That’s why a BST’s worst case efficiency is of O(n), which makes it slow.Deleting from the BST is also easy:

在这种情况下,树的行为使您遍历所有节点。 这就是为什么BST最坏情况下的效率为O(n)的原因,这使其变得很慢。从BST中删除也很容易:

  • If a node has no children →remove the node

    如果节点没有子节点,请删除该节点
  • If a node has one child →connect the parent node to its grandchild node and remove the node

    如果一个节点有一个子节点→将父节点连接到其子节点并删除该节点
  • If a node has 2 children →substitute the node for its biggest child (the rightmost left child) → see image below

    如果节点有2个子节点,请用该节点替换为其最大子节点(最右边的左子节点)→请参见下图

So now you know everything you need about BST’s. Pretty cool huh?

因此,现在您知道了有关BST的一切。 太酷了吧?

但是,如果您想始终拥有一棵高效的树怎么办? 你会怎么做? (But what if you wanted to ALWAYS have an efficient tree? What would you do?)

If you have that necessity, AVL trees can do that for you pretty well. In exchange, they are millions of times more complex than BST’s but follow the same organization as before.

如果有必要,AVL树可以为您做得很好。 作为交换,它们比BST复杂了数百万倍,但遵循与以前相同的组织。

An AVL tree is a self-balancing tree that has specific operations (called rotations) that allow the tree to stay balanced . This means that each node in the tree will have a difference of height between its two child branches of maximum 1.

AVL树是一种自平衡树,具有特定的操作(称为轮换),可以使树保持平衡。 这意味着树中的每个节点在两个最大为1的子分支之间将具有不同的高度

With this, the tree will always have a height of log(n) (n being the number of elements) and this allows you to search for elements in a really efficient way.

这样,树将始终具有log(n)的高度(n是元素的数量),这使您能够以非常有效的方式搜索元素。

So now you see how good and perfect balanced trees are. But how to make them is the real question. I have mentioned the word depth before, so let’s first understand it.

因此,现在您可以看到平衡树的完美程度。 但是如何制作它们才是真正的问题。 我之前已经提到过深度一词,所以让我们首先了解一下。

Height is what allows us to understand if our tree is balanced or not. And with it we’re able to determine where the problem is and apply the balancing functions: rotations. These are really simple functions that consist of exchanging nodes between each other in order to remove the height difference, but they might look really strange at first.

高度使我们能够了解树是否平衡。 有了它,我们就能确定问题出在哪里,并应用平衡功能: rotations 。 这些是真正简单的功能,包含相互交换节点以消除高度差的功能,但是起初它们看起来确实很奇怪。

There are 4 operations:

有4种操作:

  • Rotation Left

    向左旋转
  • Rotation Right

    向右旋转
  • Rotation Left-Right

    左右旋转
  • Rotation Right-Left

    左右旋转

哇,这很奇怪……轮换如何工作? (Wow that was strange… how do rotations work?)

Rotations are strange at first, and I suggest checking out some animations of them working.

旋转一开始是很奇怪的,我建议检查一下动画的工作原理。

Try with your own trees on this website: https://www.cs.usfca.edu/~galles/visualization/AVLtree.html

在此网站上尝试使用您自己的树木: https : //www.cs.usfca.edu/~galles/visualization/AVLtree.html

It allows you to dynamically see the rotations happening and is a great tool!There are only four cases, so understanding them will be easy.

它使您能够动态地观察到发生的旋转,并且是一个很好的工具!只有四种情况,因此了解它们很容易。

目前为止就这样了! (That’s all for now!)

Trees are pretty easy to understand, and with practice you can work with them easily. Applying them in your code is a major key to make your programs a lot more efficient.

树木很容易理解,通过实践,您可以轻松地使用它们。 在代码中应用它们是使程序更高效的主要关键。

If you have any questions about something you didn’t understand, disagree with, or would like to suggest, feel free to contact me through Twitter or by email!

如果您对您不了解的事物有任何疑问,不同意或希望提出建议,请随时通过Twitter或通过电子邮件与我联系!

Email: tiago.melo.antunes [at] tecnico [dot] ulisboa [dot] pt

电子邮件:tiago.melo.antunes [在] tecnico [点] ulisboa [点] pt

翻译自: https://www.freecodecamp.org/news/trees-in-programming-the-oxygen-of-efficient-code-6c7c11a3dd64/

氧气 电路

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值