二叉树的遍历算法实现、以及所有简单操作

来源:互联网 发布:js时间戳与php时间戳 编辑:程序博客网 时间:2024/05/29 11:38

二叉树的遍历分为先序遍历,中序遍历,后序遍历,层序遍历

先序遍历根节点->左子树->右子树

       递归思想:判断根节点是否为空,若不为空则打印根节点数据,然后调用函数取根节点左子树的数据,然后再调用函数取右子树的数据。

      递归实现:

void PrevOrder() //前序遍历{cout << "前序遍历为:";_PrevOrder(_root);cout << endl;}

void _PrevOrder(Node* root)  //根->左子树->右子树{if (root == NULL)return;cout << root->_value << " ";_PrevOrder(root->_left);_PrevOrder(root->_right);}

非递归思想:定义一个栈q,定义一个节点p指针指向根节点;将p压入栈后,取该节点的值,并且让p=p的左子树同时压入q栈中,直到左子树为空,这个时候取栈的栈顶元素,然后删除栈顶元素,并将p节点设置为根节点的右子树节点。让其再重复其上述操作。

简单流程图:



非递归实现:

void PrevOrder_NonR(){stack<Node*> q;Node* p = _root;while (p != NULL || !q.empty()){while (p != NULL){q.push(p);cout << p->_value << " ";p = p->_left;}Node* node = q.top();q.pop();p = node->_right;}cout << endl;}
中序遍历:

递归实现:

void InOrder()//中序遍历{cout << "中序遍历为:";_InOrder(_root);cout << endl;}

void _InOrder(Node* root)//左子树->根节点->右子树{if (root == NULL)return;_InOrder(root->_left);cout << root->_value << " ";_InOrder(root->_right);}
非递归想法: 定义一个栈,定义一个节点p指针指向根节点,然后将这个树的所有左子树压入栈中,然后取其栈顶的元素,然后将栈顶pop掉,让p=栈顶节点的右子树,然后重复上面的步骤。

非递归实现:

void InOrder_NonR(){stack<Node*> q;Node* p = _root;while (p != NULL || !q.empty()){while (p != NULL){q.push(p);p = p->_left;}Node* node = q.top();cout << node->_value << " ";q.pop();p = node->_right;}cout << endl;}
后序遍历:

递归实现:

void PostOrder()//后序遍历{cout << "后序遍历为:";_PostOrder(_root);cout << endl;}

void _PostOrder(Node* root)//左子树->右子树->根节点{if (root == NULL)return;_PostOrder(root->_left);_PostOrder(root->_right);cout << root->_value << " ";}

非递归实现:定义一个栈,定义一个节点指针p指向树的根节点;再定义一个节点指针prev指向上次所访问的指针,如果栈不为空或者节点p不等于NULL;则将该树的所有左子树压入栈中,然后取栈顶元素,如果这个栈顶元素的右子树为空或者是上次访问的指针,那么说明这个栈顶元素的左右子树已经遍历了,那么就打印该元素节点的数据,如果这个栈顶元素的右子树不为空或者是不是上次访问的指针,那么就让p指向栈顶元素的右子树,然后重复上述操作。

void PostOrder_NonR(){stack<Node*> s;Node* p = _root;Node* prev = NULL;while (p != NULL || !s.empty()){while (p != NULL){s.push(p);p = p->_left;}Node* node = s.top();if (node->_right == NULL || prev == node->_right){cout <<node->_value << " ";s.pop();prev = node;}else{p = node->_right;}}cout << endl;}

层序遍历:

void LevelOrder() //层序遍历{cout << "层序遍历为:";if (_root != NULL){queue<Node*> q;q.push(_root);while (!q.empty()){Node* front = q.front();cout << front->_value << " ";q.pop();if (front->_left)q.push(front->_left);if (front->_right)q.push(front->_right);}}cout << endl;}


计算深度算法:

size_t Depth() //计算树的深度{return _Depth(_root);}
size_t _Depth(Node* root){if (root == NULL)return 0;size_t left = _Depth(root->_left);size_t right = _Depth(root->_right);if (left > right){return (left + 1);}return (right + 1);}

计算节点算法:

size_t Size() //统计结点数量{return _Size(_root);}
size_t _Size(Node* root){if (root == NULL)return 0;return _Size(root->_left) + _Size(root->_right) + 1;}

计算叶节点算法:

size_t LeafSize() //统计叶结点的数量{return _LeafSize(_root);}
size_t _LeafSize(Node* root){size_t count = 0;if (root == NULL)return 0;if (root->_left == NULL && root->_right == NULL)return 1;elsereturn _LeafSize(root->_left) + _LeafSize(root->_right);}

计算满结点算法:

size_t FullSize()//计算满二叉树的结点个数{return _FullSize(_root);}
size_t _FullSize(Node* root){if (root == NULL)return 0;else if (root->_left == NULL && root->_right == NULL)return 0;else if (root->_left != NULL && root->_right == NULL)return _FullSize(root->_left);else if (root->_left == NULL && root->_right != NULL)return _FullSize(root->_right);else if (root->_left != NULL && root->_right != NULL)return _FullSize(root->_left) + _FullSize(root->_right) + 1;}

寻找节点算法:

Node* Find(const size_t& x){return _Find(_root,x);}
Node* _Find(Node* root,const size_t& x ){if (root == NULL)reutrn NULL;if (root->_value == x)return root;Node* ret = _Find(root->_left, x);if (ret != NULL)return ret;return _Find(root->_right, x);}


求K层节点数算法:

size_t GetKleve(size_t K) //获取K层结点个数{return _GetKleve(_root, K);}
size_t _GetKleve(Node* root, size_t K){assert(K > 0);if (root == NULL)return 0;if (K == 1)return 1;return _GetKleve(root->_left, K - 1) + _GetKleve(root->_right, K - 1);}

全部代码实现:

#include<iostream>using namespace std;#include<queue>#include<stack>#include<assert.h>template<class T>struct binarytreeNode{T _value;binarytreeNode<T>* _left;  //左子树binarytreeNode<T>* _right;  //右子树binarytreeNode(const T& value):_value(value), _left(NULL), _right(NULL){}};template<class T>class binarytree{typedef binarytreeNode<T> Node;public:binarytree():_root(NULL){}binarytree(T* arr, size_t n, const T& invalid = T()){size_t index = 0;_root = _Greatree(arr, n, invalid, index);}~binarytree(){_Destory(_root);}binarytree(const binarytree<T>& t){_root = Copy(t._root);}binarytree<T>& operator=(const binarytree<T>& t){if (this != t){Node* newNode = Copy(t._root);_Destory(_root);_root = newNode;}return *this;}void PrevOrder() //前序遍历{cout << "前序遍历为:";_PrevOrder(_root);cout << endl;}void PrevOrder_NonR(){stack<Node*> q;Node* p = _root;while (p != NULL || !q.empty()){while (p != NULL){q.push(p);cout << p->_value << " ";p = p->_left;}Node* node = q.top();q.pop();p = node->_right;}cout << endl;}void InOrder()//中序遍历{cout << "中序遍历为:";_InOrder(_root);cout << endl;}void InOrder_NonR(){stack<Node*> q;Node* p = _root;while (p != NULL || !q.empty()){while (p != NULL){q.push(p);p = p->_left;}Node* node = q.top();cout << node->_value << " ";q.pop();p = node->_right;}cout << endl;}void PostOrder()//后序遍历{cout << "后序遍历为:";_PostOrder(_root);cout << endl;}void PostOrder_NonR(){stack<Node*> s;Node* p = _root;Node* prev = NULL;while (p != NULL || !s.empty()){while (p != NULL){s.push(p);p = p->_left;}Node* node = s.top();if (node->_right == NULL || prev == node->_right){cout <<node->_value << " ";s.pop();prev = node;}else{p = node->_right;}}cout << endl;}void LevelOrder() //层序遍历{cout << "层序遍历为:";if (_root != NULL){queue<Node*> q;q.push(_root);while (!q.empty()){Node* front = q.front();cout << front->_value << " ";q.pop();if (front->_left)q.push(front->_left);if (front->_right)q.push(front->_right);}}cout << endl;}size_t Size() //统计结点数量{return _Size(_root);}size_t Depth() //计算树的深度{return _Depth(_root);}size_t LeafSize() //统计叶结点的数量{return _LeafSize(_root);}size_t FullSize()//计算满二叉树的结点个数{return _FullSize(_root);}size_t GetKleve(size_t K) //获取K层结点个数{return _GetKleve(_root, K);}Node* Find(const size_t& x){return _Find(_root,x);}protected:void _PrevOrder(Node* root)  //根->左子树->右子树{if (root == NULL)return;cout << root->_value << " ";_PrevOrder(root->_left);_PrevOrder(root->_right);}void _InOrder(Node* root)//左子树->根节点->右子树{if (root == NULL)return;_InOrder(root->_left);cout << root->_value << " ";_InOrder(root->_right);}void _PostOrder(Node* root)//左子树->右子树->根节点{if (root == NULL)return;_PostOrder(root->_left);_PostOrder(root->_right);cout << root->_value << " ";}size_t _Size(Node* root){if (root == NULL)return 0;return _Size(root->_left) + _Size(root->_right) + 1;}size_t _LeafSize(Node* root){size_t count = 0;if (root == NULL)return 0;if (root->_left == NULL && root->_right == NULL)return 1;elsereturn _LeafSize(root->_left) + _LeafSize(root->_right);}size_t _FullSize(Node* root){if (root == NULL)return 0;else if (root->_left == NULL && root->_right == NULL)return 0;else if (root->_left != NULL && root->_right == NULL)return _FullSize(root->_left);else if (root->_left == NULL && root->_right != NULL)return _FullSize(root->_right);else if (root->_left != NULL && root->_right != NULL)return _FullSize(root->_left) + _FullSize(root->_right) + 1;}size_t _GetKleve(Node* root, size_t K){assert(K > 0);if (root == NULL)return 0;if (K == 1)return 1;return _GetKleve(root->_left, K - 1) + _GetKleve(root->_right, K - 1);}size_t _Depth(Node* root){if (root == NULL)return 0;size_t left = _Depth(root->_left);size_t right = _Depth(root->_right);if (left > right){return (left + 1);}return (right + 1);}Node* _Find(Node* root,const size_t& x ){if (root == NULL)reutrn NULL;if (root->_value == x)return root;Node* ret = _Find(root->_left, x);if (ret != NULL)return ret;return _Find(root->_right, x);}Node* _Greatree(T* arr, size_t n,const T& invalid , size_t& index){Node * node = NULL;if (arr[index] != invalid && index < n){node = new Node(arr[index]);node->_left = _Greatree(arr, n, invalid, ++index);node->_right = _Greatree(arr, n, invalid, ++index);}  return node;}Node* Copy(Node* root){if (root == NULL)return NULL;Node* newNode = new Node(root->_value);newNode->_left = Copy(root->_left);newNode->_right = Copy(root->_right);return newNode;}void _Destory(Node* root){if (root == NULL)return;_Destory(root->_left); _Destory(root->_right);delete root;}private:Node* _root;};

测试用例:void Text(){int array[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };binarytree<int> a(array, sizeof(array) / sizeof(array[0]), '#');a.PrevOrder();a.PrevOrder_NonR();a.InOrder();a.InOrder_NonR();a.PostOrder();a.PostOrder_NonR();a.LevelOrder();cout << a.Size() << endl;cout << a.LeafSize() << endl;cout << a.Depth() << endl;cout << a.FullSize() << endl;cout << a.GetKleve(1) << endl;cout << a.GetKleve(2) << endl;cout << a.GetKleve(3) << endl;binarytree<int> b(a);}







0 0
原创粉丝点击