Data structure and algorithm go implementation heap

Time:2022-5-20

A special tree that satisfies the following two conditions:

1. The heap is always a complete binary tree (except for the last layer, all other nodes are full, and the last layer first arranges the left node)

2. The value of a node in the heap is always greater than or equal to (less than or equal to) the value of all its child nodes. If it is greater than or equal to, it is called large top pile, and if it is less than or equal to, it is small top pile.

A complete binary tree is suitable for array storage, because the subscript of an element with subscript I is 2I in its left subtree and 2I + 1 in its right subtree. The parent node is the overflow of I / 2.

Build pile

The heap is stored in an array, and the 0 subscript does not exist. It is stored from 1. The purpose of heap building is to exchange positions in place to achieve the purpose of heap building. In a complete binary tree, we know that if the subscript of the last element is n, then 1 to N / 2 are non leaf nodes and need to be stacked from top to bottom (compared with child nodes), and N / 2 + 1 to n are leaf nodes and do not need to be stacked.

Insert an element

First put the inserted element at the end of the heap, and then compare it with the parent node. If it is larger than the parent node, exchange the position, and then compare it with the parent node until the element is placed in the correct layer. This is also called bottom-up stacking.

Delete an element

If you delete the top of the heap, delete the largest element, and then find the second largest element in its child nodes and put it on the top of the heap. Look for the second largest element and then the next one

Heap sort

For example, if there are n data, we first build the data into a heap to generate a large top heap, and the number of elements is n

Get the top data (i.e. the largest element), delete the top, put the last element on the top, and then stack it into (n-1) large top heap. The time complexity of stacking is logn and the base is 2

Repeatedly obtain the top of the heap and stack it into (n-2) large top heap. The data we get is in the order from large to small.

Application of heap

Application 1: priority queue

Merge n ordered small files, take out the first element of N ordered small files, put it into the heap, take out the top of the heap to the large file, and then add one from the small file to the heap, so as to merge the elements of the small file into the large file.

Application 2: use heap to find top k (that is, find the top k data from a pile of data)

a. Create a small top heap with the size of K for static data (the data remains unchanged), traverse the array, compare the array element with the top of the heap, delete the top of the heap if it is larger than the top of the heap, and insert the element into the heap. B. compare the dynamic data (the data is constantly inserted and updated) with the top of the heap when inserting the dynamic data to see whether it is in the heap, always maintain the heap, and return it directly when necessary. The worst case is O (n * LGK)

Keyword search times: top3

a. First use hashtable to remove duplicates and accumulate the search times

b. Then create a small top heap of size k and traverse the hash table. If the number of times is greater than the top of the heap, replace the heap and push it into the heap (that is, apply the solution of 2)

When the hash table is large, it exceeds the memory requirements

  • Create n empty files, calculate the hash value of the search keyword, and take the modulus of n to obtain the file number (0 to n-1) to which the keyword is assigned

  • For each file, use hash and heap to find the TOPK respectively, and then put n topks together (for example, 10 top 20200 are very small). The K (20) keywords that appear most often are the most frequently searched in this massive data.

Go to realize large top reactor

type heap struct{
    m []int
    Len int // how many elements are there in the heap
}

func main() {
    M: = [] int {0,9,3,6,2,1,7} // the zero subscript does not put the target element
    H: = buildheap (m) // build heap and return a heap structure
    h.Push(50)
    h.Pop()
    fmt.Println(h.m)
}
/**
Build on the original slice, that is, build on the original structure
As long as the nodes with slice subscripts n / 2 to 1 are stacked in order, the whole slice will be stacked at last
 */
func buildHeap(m []int) *heap{
    n := len(m)-1
    for i:=n/2; i>0; i-- {
        heapf(m, n, i)
    }
    return &heap{m,n}
}
func (h *heap)Push(data int) {
    h.len++
    h. M = append (H.M, data) // insert data into the tail of the slice (infer that the subscript of the parent node is I / 2)
    i := h.len
    For I / 2 > 0 & & H.M [I / 2] < H.M [i] {// bottom-up heap
        h.m[i/2], h.m[i] = h.m[i], h.m[i/2]
        i = i/2
    }
}
/**
Pop up the top element. In order to prevent array holes, you need to put the last element into the top of the heap and heap it from top to bottom
 */

func (h *heap)Pop() int{
    if h.len < 1 {
        return -1
    }
    out := h.m[1]
    h. M [1] = H.M [h.len] // give the last element to the top of the heap
    h.len--
    //Pile up the top node
    heapf(h.m, h.len, 1)
    return out
}
//Heap the node with subscript i, and N represents the subscript of the last node in the heap
//2i,2i+1
func heapf(m []int, n,i int) {
    for {
        maxPos := i
        if 2*i<= n && m[2*i] > m[i] {
            maxPos = 2*i
        }
        if 2*i+1 <=n && m[2*i+1] > m[maxPos] {
            maxPos = 2*i + 1
        }
        If maxpos = = I {// if the position of node I is correct, exit
            break
        }
        m[i],m[maxPos] = m[maxPos],m[i]
        i = maxPos
    }
}

This work adoptsCC agreement, reprint must indicate the author and the link to this article

What tools have you used? Why use this tool (fast, high concurrency…)? How is the bottom layer implemented?

Recommended Today

UI automation test: Selenium + Po mode + pytest + allure integration

本人目前工作中未涉及到WebUI自动化测试,但为了提升自己的技术,多学习一点还是没有坏处的,废话不多说了,目前主流的webUI测试框架应该还是selenium,考虑到可维护性、拓展性、复用性等,我们采用PO模式去写我们的脚本,本文档也主要整合了Selenium+PO模式+Pytest+Allure,下面我们进入正题。注:文章末尾附Github地址 技术前提:python、selenium、pytest基础知识 1. 项目结构目录: image.png 2. PO模式介绍 PO模式特点: 易于维护 复用性高 脚本易于阅读理解 PO模式要素: 1. 在PO模式中抽象封装成一个BasePage类,该基类应该拥有一个只实现 webdriver 实例的属性 2. 每个一个 pag 都继承BasePage,通过driver来管理本page中元素将page中的操作封装成一个个的方法 3. TestCase依赖 page 类,从而实现相应的测试步骤 2019062515512657.png 3. BasePage 页面封装 import logging import os import time from datetime import datetime from time import sleep from selenium import webdriver from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import […]