Introduce a tree-related concept before you introduce a binary tree.
Tree definition : A tree is a collection of elements of a finite number of n (n>=0) data, shaped like an inverted tree.
The concept of a tree : node : Nodes contain data and pointers to other nodes. root node: The first node of the tree is called the root. Node degree: The number of child nodes owned by the node. leaf nodes: Nodes with no child nodes (degrees 0). Parent-child node: One node father points to another node child, children node, father as Father node sibling nodes: nodes with the same parent node are sibling nodes. ancestor of a node: all nodes that start from the root node to that node can be called ancestors of that node. descendants: Any node in a subtree that is rooted in a node is known as the descendant of that node. height of the tree: the path length of the node farthest from the root node in the tree.
the storage structure of the tree :
struct Treenode{int _data;//node value treenode* _firstchild;//left child treenode* _nextslbling;//right brother};
Tree application: File System---directory tree
After the introduction of the tree, the next introduction to the binary tree.
Binary tree definition: two fork tree is a special tree, two tree each node has a maximum of two child nodes, respectively, called the left child and the right child.
Binary Tree Type:
(1) Complete binary tree-- If set two fork tree depth is H, in addition to the H layer, the other layers (1~h-1) The number of nodes reached the maximum, the H layer all the nodes are continuously concentrated on the leftmost, this is a complete binary tree . (2) Full two fork tree-- height N of full two fork tree has 2^n-1 nodes of the two fork tree. (3) Balanced binary tree-balanced binary tree is also known as the AVL tree (different from the AVL algorithm), it is a binary sorting tree, and has the following properties: It is an empty tree or its left and right two sub-tree height difference of the absolute value of not more than 1, and about two sub-trees are a balanced binary tree.
Two The storage structure of the fork Tree :1, array representation: The binary tree structure is stored in an array way, which is to store binary tree data elements with a contiguous set of storage units. the array storage method is very effective for the storage representation of the complete binary tree, but it is not ideal to represent the general binary tree, and it is easy to cause space waste. In addition, when inserting and deleting in a tree, it is inefficient to move nodes multiple times. Chained storage solves these drawbacks. 2, chained storage means: Each node of the two-fork tree includes at least three domains: data, left child node pointer leftchild, right child node pointer rightchild. This chain-like structure is called a binary list. To make it easier to find the parent node of either node, you can add a parent pointer domain to the parent in the node, called a triple-linked list.
Template <class t>struct binarytreenode{t _value;//node value binarytreenode<t> *_left;//left child binarytreenode<t > *_right;//Right child binarytreenode (const t& value): _value (value), _left (null), _right (null) {}};
two fork Tree Nature :(1) in a non-empty binary tree, the total number of nodes in layer I does not exceed, i>=1;(2) Two fork trees with a depth of H up tonodes (H>=1), with at least h nodes;(3) for any binary tree, if its leaf node is N0, and the number of nodes with a degree of 2 is N2, then n0=n2+1;(4) The depth of a complete binary tree with n nodes is;(5) If the nodes of a complete binary tree with n nodes are stored sequentially, the nodes have the following relationship:If I is the node number, if i>1, then the parent node is numbered I/2;if 2*i<=n, then the left son (i.e. the root node of Zuozi) is numbered 2*i; if 2*i>n, there is no left son;if 2*i+1<=n, then his right son's node number is 2*i+1, if 2*i+1>n, there is no right son. (6) Given n nodes, it can form an H (n) of different two-fork trees. H (n) is the nth item of the Cattleya number. H (N) =c (2*n,n)/(n+1). (7) There is an I branch point, I is the sum of the road length of all branches, J is the sum of the road length of the leaves J=i+2i.
two cross-tree traversal:Pre-sequence traversal (first root traversal): (1) First access to the root node, (2) Pre-order access to the left subtree, (3) Pre-order access to the right subtree;1, recursive pre-sequence traversal: (1) access to the root node (2) Recursive traversal Zuozi (3) Recursive traversal right subtree2, non-recursive pre-order traversal: through the stack implementation. If the root node is not empty, the root node is pressed into the stack to access the root node, and if the Saozi right subtree of the root node is not empty, the right subtree of the node and the left subtree, access the left subtree of the root node, and if the left child of Zuozi is not empty, press left child's right node and left node, access left side of subtree, if empty, Access the right tree of the root node.
void Prevorder_nonr () //Pre-order traversal (non-recursive) {stack<binarytreenode<t>* > S;if (_root) {s.push (_root);} while (!s.empty ()) {binarytreenode<t>* top = s.top (); cout << top->_value << "; S.pop (); if (top-> _right) S.push (top->_right), if (top->_left) S.push (top->_left);} cout << Endl;}
the middle Sequence Traversal: (1) The middle sequence accesses the left subtree, (2) accesses the root node; (3) The middle sequence accesses the right subtree; 1. Recursive sequence Traversal: (1) Recursive traversal Zuozi (2) Access node (3) Recursively traverse right subtree 2, non-recursive sequence traversal: through the stack implementation. If the root node is not empty, cur points to the root node, presses all left-wing nodes, accesses the top of the stack (the leftmost node), if the right subtree of the leftmost node is not empty, cur points to the right subtree of the leftmost node, if the right subtree of the leftmost node is not empty, and if the right subtree of the leftmost node is empty Accesses the root node of the leftmost node.
void Inorder_nonr ()//Middle sequence traversal (non-recursive) {stack<binarytreenode<t>* > s; binarytreenode<t>* cur = _root;while (cur | |!s.empty ()) {//left nodes are all in the stack while (cur) {s.push (cur); cur = cur->_left;} if (!s.empty ()) {binarytreenode<t>* top = s.top (); cout << top->_value << "; S.pop (); if (top->_ right) {cur = top->_right;}}} cout << Endl;} </span>
post-sequential traversal (posterior root traversal): (1) After the following visits to the left sub-tree, (2) to visit the right sub-tree; (3) access to the root node;1. Recursive post-traversal (1) Recursive traversal Zuozi (2) recursively traverse right subtree (3) Access node2, non-recursive post-traversal: through the stack implementation.
void Postorder_nonr () //post-traversal (non-recursive) {stack<binarytreenode<t>* > s; binarytreenode<t>* cur = _root; binarytreenode<t>* Vistednode = null;while (cur | |!s.empty ()) {while (cur) {s.push (cur); cur = cur->_left;} When the right is empty or the right node equals the last accessed node, the binarytreenode<t>* top = S.top () is already accessed by the left and then subtree; if (top->_right = = NULL | | top->_right = = V Istednode) {s.pop (); cout << top->_value << ""; vistednode = top;} Else{cur = Top->_right;}} cout << Endl;}
sequence Traversal: (1) a layer of nodes traverses sequentially. Implemented through QueuesIf the root node is not empty, the root node is queued, the root node is not empty, and if the Saozi right subtree of the root node is not empty, the Saozi right subtree of the root node is entered into the queue and then accessed.
void _levelorder (binarytreenode<t>* root) {queue<binarytreenode<t>* > q;if (Root) {Q.push (root);} while (!q.empty ()) {binarytreenode<t>* front = Q.front (); cout << front->_value << ""; Q.pop (); if ( Front->_left) Q.push (Front->_left), if (front->_right) Q.push (front->_right);}}
Full code:
#include <iostream> #include <stack> #include <queue>using namespace std;template <class t> struct binarytreenode{t _value;//node value binarytreenode<t> *_left;//left child binarytreenode<t> *_right;// Right child Binarytreenode (const t& value): _value (value), _left (null), _right (null) {}};template <class T>class Binarytree{public:binarytree (): _root (NULL) {}binarytree (char *str) {_createtree (_ROOT,STR);} BinaryTree (binarytree<t>& T) {_root = _copytree (t._root);} /*binarytree& operator= (binarytree<t>& T) {if (This! = &t) {_destroy (t._root); _copytree (t._root);} return *this;} */binarytree& operator= (binarytree<t> T) {swap (_root, t._root); return *this;} ~binarytree () {_destorytree (_root);} void _createtree (binarytreenode<t>*& root,char*& str) {if (*str! = ' # ' &&*str! = ') ' {root = new Bin Arytreenode<t> (*STR), _createtree (ROOT->_LEFT,++STR), if (*str = = ') Return;_createtree (Root->_right, ++STR);}} void Prevorder_nonr () Pre-order traversal (non-recursive) {stack<binarytreenode<t>* > S;if (_root) {s.push (_root);} while (!s.empty ()) {binarytreenode<t>* top = s.top (); cout << top->_value << "; S.pop (); if (top-> _right) S.push (top->_right), if (top->_left) S.push (top->_left);} cout << Endl;} void Inorder_nonr ()//Middle sequence traversal (non-recursive) {stack<binarytreenode<t>* > s; binarytreenode<t>* cur = _root;while (cur | |!s.empty ()) {//left nodes are all in the stack while (cur) {s.push (cur); cur = cur->_left;} if (!s.empty ()) {binarytreenode<t>* top = s.top (); cout << top->_value << "; S.pop (); if (top->_ right) {cur = top->_right;}}} cout << Endl;} void Postorder_nonr ()//post-traversal (non-recursive) {stack<binarytreenode<t>* > s; binarytreenode<t>* cur = _root; binarytreenode<t>* Vistednode = null;while (cur | |!s.empty ()) {while (cur) {s.push (cur); cur = cur->_left;} When the right is empty or the right node equals the last accessed node, the binarytreenode<t>* top = S.top () is already accessed by the left and then subtree; if (top->_right = = NULL | | top->_right = = V IstEdnode) {s.pop (); cout << top->_value << ""; vistednode = top;} Else{cur = Top->_right;}} cout << Endl;} void Size ()//number of nodes {_size (_root);} void Leafnodenum ()//leaf node number {_leafnodenum (_root);} void Depth ()//depth {_depth (_root);} void Klevelnodenum ()//K-level node number {_klevelnodenum (_root);} void Prevorder ()//recursive pre-order {_prevorder (_root); cout << Endl;} void Inorder ()//recursive middle order {_inorder (_root); cout << Endl;} void Postorder ()//recursive post-shipment {_postorder (_root); cout << Endl;} void Levelorder ()//sequence traversal {_levelorder (_root); cout << Endl;} Protected:void _destorytree (binarytreenode<t>* root) {if (root) {_destorytree (root->_left); _DestoryTree ( Root->_right);d elete root;root = NULL;}} Binarytreenode<t>* _copytree (binarytreenode<t>* root) {binarytreenode<t>* CopyRoot = NULL;if (Root) {copyroot = new binarytreenode<t> (root->_value); copyroot->_left = _copytree (root->_left); copyRoot- >_right = _copytree (root->_right);} return copyroot;} int _size (binarytreenode&Lt t>* root) {if (root = NULL) {return 0;} if (Root->_left = = Null&&root->_right = = NULL) {return 1;} Else{return 1 + _size (root->left) + _size (root->_right);}} int _leafnodenum (binarytreenode<t>* root) {if (root = NULL) {return 0;} else if (Root->_left = = Null&&root->_right = = NULL) {return 1;} Else{int leftnum = _leafnodenum (root->_left); int rightnum = _leafnodenum (root->_right); return (LeftNum + rightNum );}} int _depth (binarytreenode<t>* root) {if (root = NULL) return 0;int leftdepth = _depth (root->_left); int Rightdepth = _depth (root->_right); return 1 + (Leftdepth > rightdepth? leftdepth:rightdepth);} void _klevelnodenum (binarytreenode<t>* root,int k) {if (root = NULL | | K < 1) {return 0;} else if (k = = 1) {return 1;} Else{int leftnum = _leafnodenum (root->_left,k-1);//record k-1 layer number of nodes int rightnum = _leafnodenum (root->_right,k-1) ;//The number of nodes in the K-1 layer in the right subtree return (Leftnum + Rightnum);}} void _prevorder (binarytreenode<t>* root){if (root) {cout << root->_value << ""; if (root->_left) _prevorder (root->_left); if (root->_ right) _prevorder (root->_right);}} void _inorder (binarytreenode<t>* root) {if (root) {if (root->_left) _inorder (root->_left); cout << Root->_value << ""; if (root->_right) _inorder (root->_right);}} void _postorder (binarytreenode<t>* root) {if (root) {if (root->_left) _postorder (root->_left); if (root- >_right) _postorder (root->_right) cout << root->_value << ";}} void _levelorder (binarytreenode<t>* root) {queue<binarytreenode<t>* > q;if (Root) {Q.push (root);} while (!q.empty ()) {binarytreenode<t>* front = Q.front (); cout << front->_value << ""; Q.pop (); if ( Front->_left) Q.push (Front->_left), if (front->_right) Q.push (front->_right);}} Private:binarytreenode<t> *_root;}; int main () {char* str = "12#3# #45 #6#7# #8"; binarytree<char> bt1 (str); bt1. Prevorder (); bt1. Prevorder_nOnR (); bt1. Inorder (); bt1. Inorder_nonr (); bt1. Postorder (); bt1. Postorder_nonr (); bt1. Levelorder ();//cout<< "Size:" <<bt1. Size () <<endl;//cout<< "Depth:" <<bt1. Depth () <<endl; Binarytree<char> BT2 (BT1); bt2. Prevorder_nonr (); Binarytree<char> bt3;bt3 = bt1;bt3. Prevorder_nonr (); return 0;}
Binary tree detail and binary tree pre-order, middle order, post-sequence traversal (recursive and non-recursive)