二叉树的创建及遍历

来源:互联网 发布:交友网站多语言源码 编辑:程序博客网 时间:2024/06/07 02:26

在数据处理的过程中,二叉树的大小和形态不会发生剧烈变化的情况下,适合用数组来表示二叉树的抽象数据类型。

完全二叉树一般由数组存储表示,而一般二叉树则是用链表存储表示的。

本篇将采用二叉链的存储方式对二叉树进行存储。

    二叉树的创建,使用递归前序构建二叉树。先创建根节点,在对左子树进行创建,左子树创建完成后,又对右子树进行创建。当遇到非法值时表示该子树创建完成。

    前序遍历:根节点->左节点->右节点

         递归:打印根节点的数据,打印右子树的所有数据,打印左子树的所有数据。

         非递归:定义一个栈,将根节点压栈并访问,依次将左子树压栈,左子树同样相当于一棵完整的树,重复此过程。若左子树访问完成,则将最后一个左子树退栈,访问上一个节点的右子树,依次类推,最终将会遍历整个子树。

    中序遍历及后序遍历与前序遍历类似,不同的是:

    中序遍历先访问左子树,再访问根节点,最后访问右子树。非递归实现中序遍历时,同样将根节点压栈,但是不进行访问,在左子树遍历完成后进行访问。

    后序遍历先访问左子树,再访问右子树,最后访问根节点。非递归实现后序遍历时,将根节点压栈,访问左子树,完成后访问右子树,将右子树访问完成后再访问其根节点。

    层序遍历使用队列实现。

二叉树的创建,遍历及一些简单操作的代码如下:

template<typename T>struct BinaryTreeNode              //二叉树的节点{T _data;                       //数据BinaryTreeNode<T>* _left;      //左子树BinaryTreeNode<T>* _right;     //右子树BinaryTreeNode(const T& x)     //构造函数:_data(x), _left(NULL), _right(NULL){}};template<typename T>class BinaryTree{typedef BinaryTreeNode<T> Node;public:BinaryTree()              //构造函数:_root(NULL){}BinaryTree(T* array, size_t n, const T&invalid = T())      //前序构建二叉树{size_t index = 0;_root = _CreatTreeR(array, n, invalid, index);}void PrevOrderR()       //用递归的方法前序遍历{_PrevOrderR(_root);cout << endl;}void PrevOrderNonR()     //非递归前序遍历{Node* cur = _root;stack<Node*> s;while (cur || !s.empty()){while (cur){s.push(cur);cout << cur->_data << " ";cur = cur->_left;}Node* top = s.top();s.pop();cur = top->_right;}cout << endl;}void InOrderR()          //用递归的方法中序遍历{_InOrderR(_root);cout << endl;}void InOrderNonR()     //非递归中序遍历{Node* cur = _root;stack<Node*> s;while (cur || !s.empty()){while (cur){s.push(cur);cur = cur->_left;}Node* top = s.top();cout << top->_data << " ";s.pop();cur = top->_right;}cout << endl;}void PostOrderR()      //用递归的方法后序遍历{_PostOrderR(_root);cout << endl;}void PostOrderNonR()     //非递归前序遍历{Node* cur = _root;stack<Node*> s;Node* prev = NULL;while (cur || !s.empty()){while (cur){s.push(cur);cur = cur->_left;}Node* top = s.top();if (top->_right == NULL || top->_right == prev){cout << top->_data << " ";prev = top;s.pop();}else{cur = top->_right;}}cout << endl;}void LevelOrder()      //层序遍历{queue<Node*> q;if (_root){q.push(_root);}while (!q.empty()){Node* front = q.front();cout << front->_data << " ";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 SizeR()              //递归实现求节点个数//{//return _SizeR(_root);//}size_t SizeR()          //递归实现求节点个数{size_t count = 0;return _SizeR(_root, count);}size_t GetLeafSizeR()           //递归求叶节点个数{return _GetLeafSizeR(_root);}size_t GetKLeafSizeR(size_t k)       //递归求第K层节点个数{return _GetKLeafSizeR(_root, k);}Node* FindR(const T& x)          //递归查找一个数字的位置{return _FindR(_root, x);}BinaryTree(const BinaryTree<T>& t)      //拷贝构造:_root(NULL){_root = _CopyTreeR(t._root);}BinaryTree<T>& operator=(const BinaryTree<T>&t)          //赋值运算符重载{if (this != &t){Node* root = _CopyTreeR(t._root);_DestroyR(_root);_root = root;}}~BinaryTree()            //析构函数{_DestroyR(_root);}protected:size_t _Depth(Node* root){if (root == NULL){return 0;}int left = _Depth(root->_left);int right = _Depth(root->_right);return left > right ? left : right;}Node* _CopyTreeR(Node* root){Node* head = NULL;if (root){head = new Node(root->_data);head->_left = _CopyTreeR(root->_left);head->_right = _CopyTreeR(root->_right);}return head;}void _DestroyR(Node* root){Node* del;Node* cur = root;if (cur){del = cur;_DestroyR(cur->_left);_DestroyR(cur->_right);delete del;}}Node* _CreatTreeR(T* array, size_t n, const T& invalid, size_t& index){Node* root = NULL;if (array[index] != invalid && index < n){root = new Node(array[index]);root->_left = _CreatTreeR(array, n, invalid, ++index);root->_right = _CreatTreeR(array, n, invalid, ++index);}return root;}void _PrevOrderR(Node* root){if (root == NULL){return;}cout << root->_data << " ";_PrevOrderR(root->_left);_PrevOrderR(root->_right);}void _InOrderR(Node* root){if (root == NULL){return;}_InOrderR(root->_left);cout << root->_data << " ";_InOrderR(root->_right);}void _PostOrderR(Node* root){if (root == NULL){return;}_PostOrderR(root->_left);_PostOrderR(root->_right);cout << root->_data << " ";}//size_t _SizeR(Node* root)//{//if (root == NULL)//{//return 0;//}//return _SizeR(root->_left) + _SizeR(root->_right) + 1;//}size_t _SizeR(Node* root, size_t& count){if (root == NULL){return 0;}++count;_SizeR(root->_left, count);_SizeR(root->_right, count);return count;}size_t _GetLeafSizeR(Node* root){if (root == NULL){return 0;}if (root->_left == NULL && root->_right == NULL){return 1;}else{return _GetLeafSizeR(root->_left) + _GetLeafSizeR(root->_right);}}size_t _GetKLeafSizeR(Node* cur, size_t k){if (cur == NULL){return 0;}if (k == 1){return 1;}else{return _GetKLeafSizeR(cur->_left, k - 1) + _GetKLeafSizeR(cur->_right, k - 1);}}Node* _FindR(Node* root, const T& x){if (root == NULL){return NULL;}if (root->_data == x){return root;}Node* cur = _FindR(root->_left, x);if (cur){return cur;}else{return _FindR(root->_right, x);}}protected:Node* _root;};

测试用例为:

void TestBinaryTree(){int array1[10] = { 1,2,3,'#','#',4,'#','#',5,6 };BinaryTree<int> t1(array1, sizeof(array1) / sizeof(array1[0]), '#');cout << "t1.PrevOrderR:   ";t1.PrevOrderR();cout << "t1.PrevOrderNonR:   ";t1.PrevOrderNonR();cout << "t1.InOrderR:   ";t1.InOrderR();cout << "t1.InOrderNonR:   ";t1.InOrderNonR();cout << "t1.PostOrderR:   ";t1.PostOrderR();cout << "t1.PostOrderNonR:   ";t1.PostOrderNonR();cout << "t1.LevelOrder:   ";t1.LevelOrder();cout << "t1.Size:   " << t1.SizeR() << endl;cout << "t1.Depth:   " << t1.Depth() << endl;cout << "t1.K层节点个数:   " << t1.GetKLeafSizeR(3) << endl;cout << "t1.叶节点个数:   " << t1.GetLeafSizeR() << endl;BinaryTree<int> t2(t1);cout << "t2.PrevOrderR:   ";t2.PrevOrderR();


1 0
原创粉丝点击