golang中二进制操作_二进制堆中的操作

golang中二进制操作

After reading this post you will have:

阅读这篇文章后,您将拥有:

  • A solid foundation of the heap data structure.

    堆数据结构的坚实基础。
  • Implemented a min-heap in javascript.

    在javascript中实现了最小堆。

The Binary Heap is a more complex data structure to implement from scratch. Having said that, it’s widely used in various algorithms such as:

二进制堆是从头开始实现的更复杂的数据结构。 话虽如此,它已广泛用于各种算法中,例如:

  • Graph Traversal

    图遍历
  • Sorting

    排序
  • Path-Finding

    寻找路径

For example, Google Maps (which we all know and love) uses some type of a binary heap when calculating the shortest route from point A to B.

例如,在计算从A点到B点的最短路线时,Google Maps(我们都知道并喜欢它)使用某种类型的二进制堆。

Think of a binary heap as a pile of tangerines:

将二进制堆想像成一堆橘子:

Image for post

When we want to extract a tangerine from the pile, we grab the top one for a couple of reasons:

当我们要从堆中提取橘子时,出于以下几个原因,我们选择了榜首:

  1. If we grab a tangerine from the bottom, the pile would collapse.

    如果我们从底部抓橘子,那堆就会倒塌。
  2. The top element is deemed to be the “most valuable”.

    最重要的元素被认为是“最有价值的”。

As we go down the pile of fruit, the value or priority of the tangerines decreases.

随着水果的堆积,橘子的价值或优先级降低。

The same idea applies to a binary heap.

同样的想法适用于二进制堆。

Image for post
A Max Heap
最大堆

Unlike the pile of fruit, a binary heap consists of nodes that each hold a value which could be a number, a string, or an object. Each node has a maximum of 2 children (hence the name “binary heap”), but it is possible for a node to have 1 or no children as shown above.

与水果堆不同,二进制堆由节点组成,每个节点拥有一个值,该值可以是数字,字符串或对象。 每个节点最多可以有2个子节点(因此称为“二进制堆”),但是如上所述,一个节点可以有1个子节点,也可以没有子节点。

As before, we can only extract the topmost element from the heap, which is considered to be of the “highest priority”.

和以前一样,我们只能从堆中提取最高的元素,该元素被认为是“最高优先级”

A heap in which all parent nodes are greater than or equal to the children is called a Max-Heap. While a heap in which all parent nodes are less than or equal to the children is called a Min-Heap.

所有父节点大于或等于子节点的堆称为Max-Heap 。 而所有父节点小于或等于子节点的堆称为Min-Heap

It is important to note that a binary heap should always be a complete binary tree. This means that at every level, except possibly the last, all nodes are completely filled, and all nodes are as far left as possible.

重要的是要注意, 二进制堆应该始终是完整的二进制树 。 这意味着,除了最后一个级别外,在每个级别上,所有节点都被完全填充,并且所有节点都尽可能地靠左。

An Example of a complete binary tree:

完整的二叉树的示例:

Image for post
A Complete Binary Tree
完整的二叉树

Example of an incomplete binary tree:

不完整的二叉树的示例:

Image for post
Incomplete Binary Tree
不完整的二叉树

The final step before getting into the code is understanding how a tree can be represented using an array.

进入代码之前的最后一步是了解如何使用数组表示树。

  • The root of the tree will be in position 1 of the array.

    树的根将位于数组的位置1。
  • The left child of any given node at position n, will be located at 2n.

    任何给定节点在位置n的左子节点将位于2n。
  • The right child of a node at position n will be located at position 2n + 1.

    位于位置n的节点的右子节点将位于位置2n + 1。
  • The parent of a node at position n is at position n/2.

    位于位置n的节点的父节点位于位置n / 2。

Array representation of a complete binary tree:

完整的二叉树的数组表示形式:

Image for post
[0 ,21, 64, 3, 123, 92, 32, 8, 51, 6, 2]

Tip: A complete binary tree, when represented as an array, will have no null values except for the first element at position 0.

提示 :完整的二叉树以数组表示时,除了第一个元素在位置0处,没有空值。

二进制堆中的操作 (Operations in a Binary Heap)

Our binary heap will support the following two operations:

我们的二进制堆将支持以下两个操作:

  1. Insert element.

    插入元素。
  2. Extract element.

    提取元素。

代码(最小堆) (The Code (Min Heap))

Now that we understand that a binary heap is also complete binary tree. Let’s take a closer look at the implementation of the heap operations.

现在我们知道二进制堆也是完整的二进制树。 让我们仔细看看堆操作的实现。

Let’s start by defining a javascript class:

让我们从定义一个javascript类开始:

export class MinHeap {   constructor(selector) {      this.items = [];      this.selector = selector;   }   push(){}   pop(){}}

In the above code, selector is a function provided by the user that should return the value representation of each element stored in the heap. This is done so that we can later compare the stored elements/objects.

在上面的代码中,选择器是用户提供的功能,应返回存储在堆中的每个元素的值表示形式。 这样做是为了让我们以后可以比较存储的元素/对象。

Insertion

插入

In a heap, each element is inserted at the element in the tree such that it remains a complete binary tree.

在堆中,每个元素都插入到树中的元素处,以使其保留为完整的二叉树

In the array representation, we simply append the new element at the end of the array.

在数组表示中,我们只需在数组末尾追加新元素即可。

Illustration of inserting 8 to a min heap:

在最小堆中插入8的插图:

Image for post
A new yellow node is added to the heap
一个新的黄色节点被添加到堆中

We then proceed to “bubble up” the nodes. This means we simply swap with the parent of the newly inserted node until its parent is less than or equal to it. This conserves our complete binary tree to remain a min-heap.

然后,我们继续“冒泡”节点。 这意味着我们只需与新插入节点的父节点交换,直到其父节点小于或等于它。 这样可以保存我们完整的二叉树,以保持最小堆。

Illustration:

插图:

Image for post
8 and 31 are swapped because it is a min heap
8和31被交换,因为它是最小堆
Image for post
15 and 8 are swapped, the heap property is conserved
交换15和8,保留heap属性

The code:

代码:

export class MinHeap {   constructor(selector) {      this.items = [];       this.selector = selector;   }   insert() {      let i = this.items.length;      this.items.push(item);
let parentIndex = Math.floor((i + 1) / 2 - 1);
if (parentIndex < 0) parentIndex = 0;
let parentVal = this.selector(this.items[parentIndex]); const pushedVal = this.selector(this.items[i]);
while (i > 0 && parentVal > pushedVal) { parentIndex = Math.floor((i + 1) / 2 - 1); this.swap(i, parentIndex); i = parentIndex; parentVal = this.selector( this.items[Math.max(Math.floor((i + 1) / 2 - 1), 0)] ); } }}

Remove

去掉

As mentioned, removing an element from the heap consists in taking the topmost element and then adjusting the heap so that:

如前所述,从堆中删除元素包括获取最高元素,然后调整堆,以便:

  1. It remains as a complete binary tree.

    它仍然是完整的二叉树。
  2. It remains a valid min heap.

    它仍然是有效的最小堆。

This is done by placing the last element in the heap as the topmost one and then “bubble it down” in order to conserve the min-heap property.

这是通过将堆中的最后一个元素放置为最高元素,然后“冒泡”来实现的,以保留min-heap属性。

Step-By-Step Illustration:

分步说明:

Image for post
Image for post
Image for post
Image for post

The code:

代码:

export class MinHeap {   constructor(selector) {       this.items = [];      this.selector = selector;   }
remove() { if (this.items.length <= 1) return this.items.pop(); const ret = this.items[0]; // What we will return let temp = this.items.pop(); this.items[0] = temp; // Place last element in array at front let i = 0; // We adjust heap from top to down
while (true) { let rightChildIndex = (i + 1) * 2; let leftChildIndex = (i + 1) * 2 - 1; let lowest = rightChildIndex;
if ( leftChildIndex >= this.items.length && rightChildIndex >= this.items.length ) break; if (leftChildIndex >= this.items.length) lowest = rightChildIndex; if (rightChildIndex >= this.items.length) lowest = leftChildIndex; if (!(leftChildIndex >= this.items.length) && !(rightChildIndex >= this.items.length) ) { lowest = this.selector(this.items[rightChildIndex]) < this.selector(this.items[leftChildIndex]) ? rightChildIndex : leftChildIndex; } // Find the smallest child // If the parent is greater than the smallest child: swap if (this.selector(this.items[i]) > this.selector(this.items[lowest])) { this.swap(i, lowest); i = lowest; } else break; // We have finished setting up the heap } // Return topmost element return ret; }}

After this, you may add other operations to satisfy your needs such as: isEmpty(), peek(), etc. These should be straightforward to add.

此后,您可以添加其他操作以满足您的需求,例如:isEmpty(),peek()等。这些操作应易于添加。

There you have it! That’s a simple implementation of a binary heap in javascript.

你有它! 那是用javascript二进制堆的简单实现。

If you’re curious of an application that relies heavily on a heap data structure, I built a online graph algorithms visualization playground you could check out. Link Here

如果您对一个非常依赖堆数据结构的应用程序感到好奇,那么我就建立了一个在线图形算法可视化游乐场,您可以签出它。 在这里链接

Originally published at MyBlog.

最初发表在 MyBlog上

翻译自: https://medium.com/dev-genius/how-to-implement-a-binary-heap-javascript-d3a0c54112fa

golang中二进制操作

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值