basic terms of a tree
1. Node: {Data element + several branches pointing to subtree}
2. Node Degree: Number of branches (number of subtrees)
3. Tree degree: The maximum of the degree of all nodes in the tree
4. Leaf nodes: zero-degree nodes
5. Branch nodes: nodes with degrees greater than 0 (with root and intermediate nodes)
6. Path (from root to Node): composed of branches and nodes from the root to the node;
7. Hierarchy of nodes: Assuming that the root node is at level 1, the child of the root is the 2nd layer, and if a node is in the L layer, the root of its subtree is in the l+1 layer.
8. Depth of tree: The largest layer of leaf nodes in the tree;
Two fork Tree
Binary tree or empty tree, or by a root node plus two, called Saozi right subtree, the non-intersection of the two-fork tree composition. (The maximum number of trees is 2)
The important properties of a binary tree:
Property 1: There are at most 2^ (i-1) nodes on the first layer of the binary tree (i≥1);
Property 2: Two-fork tree with a depth of K (2^k)-1 nodes (k≥1);
Property 3: For any binary tree, if it contains n0 leaf nodes (0 degree nodes), N2 degrees 2 nodes, then there must be a relationship: N0 = n2+1.
Two special types of two-fork trees:
full two fork tree: refers to a two-fork tree with a depth of k and containing (2^k)-1 nodes.
Complete binary tree: The N nodes contained in the tree correspond to the nodes one by one in the tree with a number 1 to n in the full two. (numbered rules are, from top to bottom, from left to right.) as shown)
Features of the complete binary tree:
1. Leaf nodes appear on the last 2 layers
2. For any node, if the maximum level of the descendants under the right branch is L, the maximal level of the descendants under the left branch is L or l+1;
Property 4: The depth of a complete binary tree with n nodes is [Logn] (rounded down) +1.
Property 5: if the N a complete binary tree of nodes from top to bottom and from left to right . 1 to N the number of the complete binary tree is numbered I the node:
(1) If i=1, then the node is the root of two fork tree, no parents, otherwise, the number is [I/2] (downward rounding) node for its parents node;
(2) If 2i>n, then the node has no left child, otherwise, the node numbered 2i for its left child node;
(3) If 2i+1>n, then the node has no right child node, otherwise, the node numbered 2i+1 is the right child node.
two-tree-chained storage implementation
Description
Because this blog is only to demonstrate the theory of binary tree, so the code does not have the packaging and usability is not ideal, but because in the actual application, it is basically impossible to use the two-fork tree directly, so there is no way to optimize him, in this first to say sorry to everyone;
Binary tree Node construction
Template <typename type>class treenode{ friend class binarytree<type>;//because this is just for demonstration, It is therefore defined as Publicpublic: TreeNode (const type &_data = Type (), TreeNode *_left = null, TreeNode *_right = null) : D ATA (_data), Leftchild (_left), Rightchild (_right) {} Type data; TreeNode *leftchild; TreeNode *rightchild;};
Binary tree construction :
Template <typename type>class binarytree{public: //Two fork tree can be manipulated BinaryTree (): root (NULL) {} bool IsEmpty () const { return root = = NULL ; } First-order traversal of Void preorder () const { return preorder (root); } Middle order traversal void inorder () const { return inorder (root); } Subsequent traversal of void Postorder () const { return postorder (root); } Hierarchy traversal void Levelorder () const;private: void Preorder (const treenode<type> *rootnode) const; void Inorder (const treenode<type> *rootnode) const; void Postorder (const treenode<type> *rootnode) const; void visit (const treenode<type> *node) const;//because it is only for demonstration purposes, it is defined as Publicpublic: treenode<type> * Root;};
First (root) sequence traversal algorithm:
1. If the binary tree is empty, it is returned directly;
2. otherwise
(1) Access to the root node (visit);
(2) The first sequence traverses the left subtree;
(3) The first sequence traverses the right sub-tree;
Implement template <typename type>void Binarytree<type>::p reorder (const treenode<type> *subtree) const{ if (subtree! = NULL) { visit (subtree); Preorder (subtree->leftchild); Preorder (subtree->rightchild); }}
The traversal algorithm in the (root) sequence:
1. If the binary tree is empty tree, then empty operation;
2. otherwise
(1) The middle sequence traverses the left subtree;
(2) Access to the root node;
(3) The middle sequence traverses the right sub-tree.
Implement template <typename type>void binarytree<type>::inorder (const treenode<type> *subTree) const{ if (subtree! = NULL) { inorder (subtree->leftchild); Visit (subtree); Inorder (Subtree->rightchild); }}
Traversal algorithm for post (root) Order:
1. If the binary tree is empty tree, then empty operation;
2. otherwise
(1) to traverse the left subtree;
(2) to traverse the right sub-tree;
(3) Access to the root node.
Implement template <typename type>void Binarytree<type>::p ostorder (const treenode<type> *subtree) const{ if (subtree! = NULL) { postorder (subtree->leftchild); Postorder (subtree->rightchild); Visit (subtree); }}
Hierarchical traversal algorithm and visit operation:
Template <typename type>void binarytree<type>::levelorder () const{ std::queue< TreeNode<Type >* > queue; Queue.push (root); while (!queue.empty ()) { treenode<type> *currentnode = Queue.front (); Queue.pop (); Visit (CurrentNode); if (currentnode->leftchild! = NULL) queue.push (currentnode->leftchild); if (currentnode->rightchild! = NULL) queue.push (currentnode->rightchild);} }
Template <typename type>void binarytree<type>::visit (const treenode<type> *currentnode) const{ cout << currentnode->data << ";}
Binary tree construction and application example
Construct a two-fork tree as follows:
The code is as follows int main () { binarytree<char> tree; treenode<char> addition (' + '), subtraction ('-'), Multiplies (' * '), divides ('/'); Treenode<char> A (' a '), B (' B '), C (' C '), D (' d '), E (' e '); Tree.root = &addition; Addition.leftchild = &subtraction; Addition.rightchild = &e; Subtraction.leftchild = &multiplies; Subtraction.rightchild = &d; Multiplies.leftchild =÷s; Multiplies.rightchild = &c; Divides.leftchild = &a; Divides.rightchild = &b; cout << "Preorder:"; Tree.preorder (); cout << Endl; cout << "inorder:"; Tree.inorder (); cout << Endl; cout << "Postorder:"; Tree.postorder (); cout << Endl; cout << "Level Order"; Tree.levelorder (); cout << Endl; return 0;}
Application examples of traversal algorithms
1. Count the number of leaf nodes in a binary tree (first-order traversal)
2. Find the depth of the binary tree (post-order traversal)
3. Duplicate binary tree (post-secondary traversal)
Data Structure Basics (16)--tree and two-fork tree