Home Web Front-end JS Tutorial js implements data structure: tree and binary tree, binary tree traversal and basic operation methods

js implements data structure: tree and binary tree, binary tree traversal and basic operation methods

Sep 22, 2017 am 09:55 AM
javascript Basic operations data structure

Tree structure is a very important type of nonlinear structure. Intuitively, a tree structure is a hierarchical structure defined by branching relationships.

Trees are also widely used in the computer field. For example, in compilers, trees are used to represent the grammatical structure of the source program; in database systems, trees can be used to organize information; when analyzing the behavior of algorithms , trees can be used to describe its execution process, etc.

First, let’s look at some concepts of trees: 1. Tree (Tree) is a finite set of n (n>=0) nodes. In any non-empty tree:

  (1) There is and is only one specific node called the root;

  (2) When n>1, The remaining nodes can be divided into m (m>0) mutually disjoint finite sets T1, T2, T3,...Tm, each of which is itself a tree and is called the subtree of the root.

For example, (a) is a tree with only one root node; (b) is a tree with 13 nodes, where A is the root, and the remaining nodes are divided into 3 disjoint subsets: T1={B,E,F,K,L},t2={D,H,I,J,M};T1, T2 and T3 are all subtrees of root A and are themselves a tree.
js implements data structure: tree and binary tree, binary tree traversal and basic operation methods

2. The node of the tree contains a data element and several branches pointing to its subtrees. The number of subtrees a node has is called the degree of the node. For example, in (b), the degree of A is 3, the degree of C is 1, and the degree of F is 0. The node with degree 0 is called a leaf or terminal node. Nodes with degree other than 0 are called non-terminal nodes or branch nodes. The degree of a tree is the maximum degree of each node in the tree. The degree of the tree in (b) is 3. The root of the subtree of a node is called the child of the node. Correspondingly, this node is called the child's parent. Children of the same parents call each other siblings. The ancestors of a node are all nodes on the branches from the root to the node. On the contrary, any node in the subtree rooted at a node is called a descendant of that node.

3. The node level (Level) is defined starting from the root, the root is the first level, and the following children are the second level. If a node is at level l, then the root of its subtree is at level l+1. The nodes whose parents are on the same level are cousins ​​of each other. For example, nodes G and E, F, H, I, and J are cousins ​​of each other. The maximum level of nodes in the tree is called the depth or height of the tree. The depth of the tree in (b) is 4.

4. If the subtrees of the nodes in the tree are viewed as ordered from left to right (that is, they cannot be exchanged), then the tree is called an ordered tree, otherwise it is called an unordered tree. In an ordered tree, the root of the leftmost subtree is called the first child, and the root of the rightmost subtree is called the last child.

5. Forest is a collection of m (m>=0) disjoint trees. For each node in the tree, the set of its subtrees is the forest.

Let’s take a look at concepts related to binary trees:

Binary Tree is another tree structure. Its characteristic is that each node has at most two subtrees (i.e. binary tree). There is no node with degree greater than 2), and the subtrees of a binary tree can be divided into left and right subtrees (the order cannot be reversed arbitrarily.)

Properties of binary trees:

1. In the binary tree There are at most 2 i-1 power nodes on the i-th layer (i>=1).

 2. A binary tree with depth k has at most 2 k-th power - 1 nodes, (k>=1).

 3. For any binary tree T, if the number of terminal nodes is n0 and the number of nodes with degree 2 is n2, then n0 = n2 + 1;

 The depth of the tree is k And a binary tree with 2 k-1 nodes is called a full binary tree.

A binary tree with n nodes of depth k, if and only if each node corresponds to the nodes numbered from 1 to n in the full binary tree of depth k, It is called a complete binary tree.

The following are two characteristics of a complete binary tree:

4. The depth of a complete binary tree with n nodes is Math.floor(log 2 n) + 1

5. If the nodes of a complete binary tree with n nodes (its depth is Math.floor(log 2 n) + 1) are numbered in layer order (from the 1st level to the Math.floor(2 n) + 1, each layer from left to right), then for any node (1

  (1) If i=1, then node i is a binary tree Root, no parents; if i>1, then its parent(i) is the node Math.floor(i/2).

  (2) If 2i > n, then node i has no left child (node ​​i is a leaf node); otherwise its left child LChild(i) is node 2i.

  (3) If 2i + 1 > n, then node i has no right child; otherwise its right child RChild(i) is node 2i + 1;
js implements data structure: tree and binary tree, binary tree traversal and basic operation methods

js implements data structure: tree and binary tree, binary tree traversal and basic operation methods

##Storage structure of binary tree

1. Sequential storage structure
Use a set of continuous storage units to store the node elements on the complete binary tree from top to bottom and from left to right, that is, the node element numbered i on the binary tree is stored in the In the component with subscript i-1 in the one-dimensional array defined above. "0" means that this node does not exist. This sequential storage structure is only suitable for complete binary trees.
Because, in the worst case, a single tree with depth k and only k nodes (there is no node with degree 2 in the tree) requires a length of 2 to the nth power -1 dimensional array.

2. Linked storage structure
The node of a binary tree consists of a data element and two branches pointing to its left and right subtrees respectively, which means that the nodes in the linked list of the binary tree contain at least three fields. : Data field and left and right pointer fields. Sometimes, in order to facilitate finding the parents of a node, a pointer field pointing to its parent node can be added to the node structure. The storage structures of binary trees obtained by using these two structures are called binary linked lists and triple linked lists respectively.
There are n+1 empty link fields in a binary linked list containing n nodes. We can use these empty link fields to store other useful information, thereby obtaining another linked storage structure-clue linked list.

There are three main types of binary tree traversal:

First (root) order traversal: root left and right
Middle (root) order traversal: left root right
Back (root) order Traversal: Left and right roots

Sequential storage structure of binary tree:

js implements data structure: tree and binary tree, binary tree traversal and basic operation methods

Chained storage form of binary tree:

js implements data structure: tree and binary tree, binary tree traversal and basic operation methods

// 顺序存储结构
    var tree = [1, 2, 3, 4, 5, , 6, , , 7];
    // 链式存储结构
    function BinaryTree(data, leftChild, rightChild) {
        this.data = data || null;
        // 左右孩子结点
        this.leftChild = leftChild || null;
        this.rightChild = rightChild || null;
    }
Copy after login

Traversing Binary Tree: refers to visiting each node in the binary tree once and only once according to the specified rules.

1. Preorder traversal of the binary tree

1) The recursive definition of the algorithm is:

If the binary tree is empty, the traversal ends; otherwise

 ⑴ Access Root node;

 ⑵Traverse the left subtree in order (call this algorithm recursively);

 ⑶Traverse the right subtree in order (call this algorithm recursively).

Algorithm implementation:

// 顺序存储结构的递归先序遍历
    var tree = [1, 2, 3, 4, 5, , 6, , , 7];    console.log('preOrder:');
    void function preOrderTraverse(x, visit) {
        visit(tree[x]);
        if (tree[2 * x + 1]) preOrderTraverse(2 * x + 1, visit);
        if (tree[2 * x + 2]) preOrderTraverse(2 * x + 2, visit);
    }(0, function (value) {
        console.log(value);
    });
    // 链式存储结构的递归先序遍历
    BinaryTree.prototype.preOrderTraverse = function preOrderTraverse(visit) {
        visit(this.data);
        if (this.leftChild) preOrderTraverse.call(this.leftChild, visit);
        if (this.rightChild) preOrderTraverse.call(this.rightChild, visit);
    };
Copy after login

2) Non-recursive algorithm:

Assume T is a variable pointing to the root node of the binary tree, the non-recursive algorithm is: If the binary tree is empty, then Return; otherwise, let p=T;

 (1) p is the root node;

 (2) If p is not empty or the stack is not empty;

(3) If p is not empty, access the node pointed by p, push p onto the stack, p = p.leftChild, access the left subtree;

  (4) Otherwise; pop back to p, then p = p.rightChild, access the right subtree

 (5) Go to (2) until the stack is empty.

Code implementation:

// 链式存储的非递归先序遍历

    // 方法1
    BinaryTree.prototype.preOrder_stack = function (visit) {        
    var stack = new Stack();        
    stack.push(this);        
    while (stack.top) {            
    var p;            // 向左走到尽头
            while ((p = stack.peek())) {
                p.data && visit(p.data);                
                stack.push(p.leftChild);
            }            
            stack.pop();            
            if (stack.top) {
                p = stack.pop();                
                stack.push(p.rightChild);
            }
        }
    };    // 方法2
     BinaryTree.prototype.preOrder_stack2 = function (visit) {        
     var stack = new Stack();        
     var p = this;        
     while (p || stack.top) {            
     if (p) {                
     stack.push(p);
                p.data && visit(p.data);
                p = p.leftChild;
            } else {
                p = stack.pop();
                p = p.rightChild;
            }
        }
    };
Copy after login

2. In-order traversal of the binary tree:

1) The recursive definition of the algorithm is:

If the binary tree is empty, then traverse End; otherwise

 ⑴ In-order traverse the left subtree (recursively call this algorithm);

 ⑵ Visit the root node; call this algorithm).

// 顺序存储结构的递归中序遍历
    var tree = [1, 2, 3, 4, 5, , 6, , , 7];    
    console.log('inOrder:');
    void function inOrderTraverse(x, visit) {        
    if (tree[2 * x + 1]) inOrderTraverse(2 * x + 1, visit);
        visit(tree[x]);
        if (tree[2 * x + 2]) inOrderTraverse(2 * x + 2, visit);
    }(0, function (value) {
        console.log(value);
    });

    // 链式存储的递归中序遍历
    BinaryTree.prototype.inPrderTraverse = function inPrderTraverse(visit) {        
    if (this.leftChild) inPrderTraverse.call(this.leftChild, visit);
        visit(this.data);
        if (this.rightChild) inPrderTraverse.call(this.rightChild, visit);
    };
Copy after login

2) Non-recursive algorithm

T is a variable pointing to the root node of the binary tree. The non-recursive algorithm is: If the binary tree is empty, return; otherwise, let p=T

 ⑴ If p is not empty, p is pushed onto the stack, p=p.leftChild;

<br/>
Copy after login

 ⑵ Otherwise (that is, p is empty), push back to p and access the node pointed by p, p =p.rightChild;

 ⑶ Go to (1);

Until the stack is empty.

 

// 方法1
    inOrder_stack1: function (visit) {        
    var stack = new Stack();        
    stack.push(this);        
    while (stack.top) {            
    var p;            // 向左走到尽头
            while ((p = stack.peek())) {                
            stack.push(p.leftChild);
            }            
            stack.pop();            
            if (stack.top) {
                p = stack.pop();
                p.data && visit(p.data);                
                stack.push(p.rightChild);
            }
        }
    },    // 方法2
    inOrder_stack2: function (visit) {        
    var stack = new Stack();        
    var p = this;        
    while (p || stack.top) {            
    if (p) {                
    stack.push(p);
                p = p.leftChild;
            } else {
                p = stack.pop();
                p.data && visit(p.data);
                p = p.rightChild;
            }
        }
    },
Copy after login
<br/>3. Post-order traversal of the binary tree:

1) Recursive algorithm

If the binary tree is empty, the traversal ends; otherwise

 ⑴ Post-order traversal of the left subtree (recursively calling this algorithm);

 ⑵ Post-order traversal of the right subtree (recursive call of this algorithm);

 ⑶ Visit the root node.

// 顺序存储结构的递归后序遍历
    var tree = [1, 2, 3, 4, 5, , 6, , , 7];    
    console.log(&#39;postOrder:&#39;);
    void function postOrderTraverse(x, visit) {        
    if (tree[2 * x + 1]) postOrderTraverse(2 * x + 1, visit);
        if (tree[2 * x + 2]) postOrderTraverse(2 * x + 2, visit);
        visit(tree[x]);
    }(0, function (value) {
        console.log(value);
    });
    // 链式存储的递归后序遍历
    BinaryTree.prototype.postOrderTraverse = function postOrderTraverse(visit) {        
    if (this.leftChild) postOrderTraverse.call(this.leftChild, visit);
        if (this.rightChild) postOrderTraverse.call(this.rightChild, visit);
        visit(this.data);
    };
Copy after login
<br/>2) Non-recursive algorithm

In post-order traversal, the root node is the last one visited. Therefore, during the traversal process, when the search pointer points to a certain root node, it cannot be accessed immediately, but its left subtree must be traversed first, and the root node is pushed onto the stack. When the root node is searched after traversing its left subtree, it is still inaccessible, and its right subtree needs to be traversed. Therefore, the root node needs to be pushed onto the stack again. When its right subtree is traversed and then popped back onto the stack, it can be accessed. Therefore, set up a status flag variable mark:

mark=0 means that this node has just been accessed, mark=1 means that the left subtree processing is completed and returned,

mark=2 means that the right subtree is processed End return. Each time the action is decided based on the mark field on the top of the stack

Algorithm implementation idea:

 (1) The root node is pushed into the stack, and mark = 0;

 (2 ) If the stack is not empty, pop it to the node;

 (3) If the mark of the node = 0, modify the mark of the current node to 1, and push the left subtree onto the stack;

 (4 ) If the mark of the node = 1, modify the mark of the current node to 2, and push the right subtree onto the stack;

  (5) If the mark of the node = 2, access the value of the current node node;

 (6) End until the stack is empty.

 

postOrder_stack: function (visit) {
        var stack = new Stack();        
        stack.push([this, 0]);        
        while (stack.top) {
            var a = stack.pop();
            var node = a[0];            
            switch (a[1]) {                
            case 0:                    
            stack.push([node, 1]);  // 修改mark域
                    if (node.leftChild) stack.push([node.leftChild, 0]);  // 访问左子树
                    break;                
                    case 1:                    
                    stack.push([node, 2]);                    
                    if (node.rightChild) stack.push([node.rightChild, 0]);                    
                    break;                
                    case 2:
                    node.data && visit(node.data);                    
                    break;                
                    default:                    
                    break;
            }
        }
    }
Copy after login
<br/>A specific example

<html>
  <head>
    <meta charset="utf-8">
    <title>文档标题</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="renderer" content="webkit">
    <meta name="keywords" content="your keywords">
    <meta name="description" content="your description">
    <link rel="shortcut icon" type="image/ico" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0"></head><body>
    <p class="container"></p>
    <script>
   // 顺序存储结构
   (function () {
       // 顺序存储结构的遍历
       var tree = ["a","b","c","d","e","f","g"];

       console.log(&#39;preOrder:&#39;);
       +function preOrderTraverse(x, visit) {
           visit(tree[x]);           
           if (tree[2 * x + 1]) preOrderTraverse(2 * x + 1, visit);           
           if (tree[2 * x + 2]) preOrderTraverse(2 * x + 2, visit);
       }(0, function (value) {
           console.log(value);
       });

       console.log(&#39;inOrder:&#39;);       
       void function inOrderTraverse(x, visit) {
           if (tree[2 * x + 1]) inOrderTraverse(2 * x + 1, visit);
           visit(tree[x]);          
           if (tree[2 * x + 2]) inOrderTraverse(2 * x + 2, visit);
       }(0, function (value) {
           console.log(value);
       });

       console.log(&#39;postOrder:&#39;);       
       void function postOrderTraverse(x, visit) {
           if (tree[2 * x + 1]) postOrderTraverse(2 * x + 1, visit);           
           if (tree[2 * x + 2]) postOrderTraverse(2 * x + 2, visit);
           visit(tree[x]);
       }(0, function (value) {
           console.log(value);
       });
   }());   // 求从tree到node结点路径的递归算法
   function findPath(tree, node, path, i) {
       var found = false;       
       void function recurse(tree, i) {
           if (tree == node) {
               found = true;              
               return;
           }

           path[i] = tree;           
           if (tree.leftChild) recurse(tree.leftChild, i + 1);           
           if (tree.rightChild && !found) recurse(tree.rightChild, i + 1);           
           if (!found) path[i] = null;
       }(tree, i);
   }   var global = Function(&#39;return this;&#39;)();    
   </script>
 </body>
</html>
Copy after login

The above is the detailed content of js implements data structure: tree and binary tree, binary tree traversal and basic operation methods. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Compare complex data structures using Java function comparison Compare complex data structures using Java function comparison Apr 19, 2024 pm 10:24 PM

When using complex data structures in Java, Comparator is used to provide a flexible comparison mechanism. Specific steps include: defining the comparator class, rewriting the compare method to define the comparison logic. Create a comparator instance. Use the Collections.sort method, passing in the collection and comparator instances.

In-depth understanding of reference types in Go language In-depth understanding of reference types in Go language Feb 21, 2024 pm 11:36 PM

Reference types are a special data type in the Go language. Their values ​​do not directly store the data itself, but the address of the stored data. In the Go language, reference types include slices, maps, channels, and pointers. A deep understanding of reference types is crucial to understanding the memory management and data transfer methods of the Go language. This article will combine specific code examples to introduce the characteristics and usage of reference types in Go language. 1. Slices Slices are one of the most commonly used reference types in the Go language.

Java data structures and algorithms: in-depth explanation Java data structures and algorithms: in-depth explanation May 08, 2024 pm 10:12 PM

Data structures and algorithms are the basis of Java development. This article deeply explores the key data structures (such as arrays, linked lists, trees, etc.) and algorithms (such as sorting, search, graph algorithms, etc.) in Java. These structures are illustrated through practical examples, including using arrays to store scores, linked lists to manage shopping lists, stacks to implement recursion, queues to synchronize threads, and trees and hash tables for fast search and authentication. Understanding these concepts allows you to write efficient and maintainable Java code.

Full analysis of Java collection framework: dissecting data structure and revealing the secret of efficient storage Full analysis of Java collection framework: dissecting data structure and revealing the secret of efficient storage Feb 23, 2024 am 10:49 AM

Overview of Java Collection Framework The Java collection framework is an important part of the Java programming language. It provides a series of container class libraries that can store and manage data. These container class libraries have different data structures to meet the data storage and processing needs in different scenarios. The advantage of the collection framework is that it provides a unified interface, allowing developers to operate different container class libraries in the same way, thereby reducing the difficulty of development. Data structures of the Java collection framework The Java collection framework contains a variety of data structures, each of which has its own unique characteristics and applicable scenarios. The following are several common Java collection framework data structures: 1. List: List is an ordered collection that allows elements to be repeated. Li

PHP data structure: The balance of AVL trees, maintaining an efficient and orderly data structure PHP data structure: The balance of AVL trees, maintaining an efficient and orderly data structure Jun 03, 2024 am 09:58 AM

AVL tree is a balanced binary search tree that ensures fast and efficient data operations. To achieve balance, it performs left- and right-turn operations, adjusting subtrees that violate balance. AVL trees utilize height balancing to ensure that the height of the tree is always small relative to the number of nodes, thereby achieving logarithmic time complexity (O(logn)) search operations and maintaining the efficiency of the data structure even on large data sets.

Learn the secrets of Go language data structures in depth Learn the secrets of Go language data structures in depth Mar 29, 2024 pm 12:42 PM

In-depth study of the mysteries of Go language data structure requires specific code examples. As a concise and efficient programming language, Go language also shows its unique charm in processing data structures. Data structure is a basic concept in computer science, which aims to organize and manage data so that it can be accessed and manipulated more efficiently. By in-depth learning the mysteries of Go language data structure, we can better understand how data is stored and operated, thereby improving programming efficiency and code quality. 1. Array Array is one of the simplest data structures

Basic operating skills of office ppt software Basic operating skills of office ppt software Mar 19, 2024 pm 07:52 PM

Many corporate employees usually use ppt for presentation when making project presentations. Making a ppt with pictures and text is more enjoyable to display. Therefore, ppt is as important to an office worker as word and Excel, and they are all necessary office software. It is very necessary to master some basic operating skills. 1. First, let us take a look at the menu bar in PPT. As you can see, the red frame is the function bar of PPT. Including &quot;Start&quot;, &quot;Insert&quot;, &quot;Design&quot;, &quot;Animation&quot;, &quot;Slide Show&quot;, &quot;Review&quot;, &quot;View&quot;. In addition, in the upper left corner, the orange box &quot;WPS Demo&quot; also contains many commonly used functions. 2. Start &quot;Start&quot;, its functions include many other menus

Python performance optimization practice: from basics to advanced Python performance optimization practice: from basics to advanced Feb 20, 2024 pm 12:00 PM

Basic Optimizations Use the correct Python version: Newer versions of python are generally more performant, offer better memory management and built-in optimizations. Choose the right library: You can save time and improve performance by using purpose-built libraries instead of writing code from scratch. Reduce the number of loops: If possible, avoid using nested loops. Using list comprehensions and generator expressions are more efficient alternatives. Data structure optimization chooses the right container: lists are good for random access, dictionaries are good for fast key-value lookups, and tuples are good for immutable data. Use preallocated memory: By preallocating the size of an array or list, you can reduce the overhead of memory allocation and defragmentation. Leveraging Numpy and Pandas: For scientific computing and data analysis, Num

See all articles