二叉树
来源:互联网 发布:湖南软件测试 编辑:程序博客网 时间:2024/06/05 21:02
定义
二叉树在图论中是这样定义的:二叉树是一个连通的无环图,并且每一个顶点的度不大于3.有根二叉树还要满足根节点的度不大于2.有了根节点之后,每个顶点定义了唯一的父节点,和做多2个子节点.然而,没有足够的信息来区分做节点和右节点.如果不考虑连通性,允许途中有多个连通分量,这种结构叫做森林.
分类
- 完全二叉树——若设二叉树的高度为h,除第h层外,其他各层的节点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树
- 满二叉树——–除了叶子结点外每一个节点都有左右子节点,且叶子节点都处在最底层的二叉树
- 平衡二叉树——-平衡二叉树又被称为AVL树,它是一颗二叉排序树,且具有以下性质:(1)它是一颗空树或它的左右两个字数的高度差绝对值不超过1,(2)左右两个字数都是一颗平衡二叉树.
相关名词
树的节点:包含一个数据元素及若干指向子树的分支;
孩子节点:节点的子树的跟
双亲节点:A节点是B的孩子,则B是A的双亲
兄弟节点:同一双亲的孩子节点;
堂兄节点:同一层上的节点;
祖先节点:从根到该节点的所经分支上的所有节点;
子孙节点:一某节点为根的子树中任一节点都称为该节点的子孙;
节点层:根节点的层恒为1,根的孩子为第二层节点,以此类推;
树的深度:书中最大的节点层;
节点的度:节点子树的个数;
树的度:书中最大的节点数;
叶子结点:度为0的节点;
分枝节点:度不为0 的节点;
有序树:子树有序的树,如:家族树;
无序树:不考虑子树的顺序的树.
主要代码实现(前中后序遍历(递归,非递归),线索化,二叉搜索树转换成一个有序的双向链表)
#pragma once#include<iostream> #include<queue> #include<stack>using namespace std; template<class T> struct BinaryTreeNode { BinaryTreeNode(const T& data) :_data(data) ,_left(NULL) ,_right(NULL) {} BinaryTreeNode<T>* _left; BinaryTreeNode<T>* _right; T _data; }; template<class T> class BinaryTree { typedef BinaryTreeNode<T> Node; public: BinaryTree(); BinaryTree(const T* a,size_t size,const T& invalid) :_root(NULL) { size_t index=0; _root=_GreateTree(a,size,index,invalid); } Node* _GreateTree(const T *a, size_t size, size_t& index, const T& invalid) { Node* root = NULL; if (a[index] != invalid&&index<size) { root = new Node(a[index]); root->_left = _GreateTree(a, size, ++index, invalid); root->_right = _GreateTree(a, size, ++index, invalid); } return root; } BinaryTree(const BinaryTree<T>& t) { _root=_Copy(t._root) ; } void PrevOrder() //前序 { _PrevOrder(_root); cout<<endl; } void PrevOrderNonR() //非递归 栈 { stack<Node*> s; Node* cur=_root; while(cur||!s.empty ()) { while(cur) //把左子树访问完 { cout<<cur->_data <<" "; s.push (cur); cur=cur->_left ; } Node* top=s.top (); s.pop (); cur=top->_right ; } cout<<endl; } void InOrder() //中序 { _InOrder(_root); cout<<endl; } void InOrderNonR() { stack<Node*> s; Node* cur=_root; 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 PostOrder() //后序 { _PostOrder(_root); cout<<endl; } void PostOrderNonR() { stack<Node*> s; Node* cur=_root; 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; } //找第K层节点的个数 size_t FindKLeve(size_t k) { return _FindKLeve(_root,k); } //叶子节点个数 size_t LeafNum() { return _LeafNum(_root); } ~BinaryTree() { _Destory(_root); } size_t Size() { return _Size(_root); } size_t Depth() { return _Depth(_root); } Node* Find(const T& x) { return _Find(_root,x); } void LeveOder() //层次遍历 队列 { 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; } protected: size_t _LeafNum(Node* root) { static size_t count=0; if(root==NULL) return count; if((root->_left ==NULL)&&(root->_right ==NULL)) { ++count; return count; } _LeafNum(root->_left ); _LeafNum(root->_right ); } size_t _FindKLeve(Node* root,size_t k) { if(root==NULL) return 0; if(k==1) return 1; return _FindKLeve(root->_left ,k-1)+_FindKLeve(root->_right ,k-1); } Node* _Find(Node* root,const T& x) { if(root==NULL) return NULL; if(root->_data==x ) return root; Node* ret=_Find(root->_left,x ); //左子树没有找到,从右子树找 if(ret==NULL) { ret=_Find(root->_right ,x); } return ret; } size_t _Depth(Node* root) { if(root==NULL) return 0; size_t LefD=_Depth(root->_left ); size_t RigD=_Depth(root->_right ); return LefD>RigD?LefD+1:RigD+1; } size_t _Size(Node* root) {/* static size_t count=0; if(root==NULL) { return 0; } ++count; _Size(root->_left ); _Size(root->_right ); return count;*/ if(root==NULL) return 0; return _Size(root->_left )+_Size(root->_right )+1; } void _Destory(Node* root) { if(root) { _Destory(root->_left ); _Destory(root->_right ); delete root; } } void _PostOrder(Node* root) { if(root) { _PostOrder(root->_left ); _PostOrder(root->_right ); cout<<root->_data <<" "; } } void _PostOrderNonR(Node*cur)//后序遍历二叉树非递归版本 { 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) { s.pop(); prev = top; } else//子问题 { cur = top->_right; } cout >> endl; } } void _InOrder(Node* root) { if(root) { _InOrder(root->_left ); cout<<root->_data <<" "; _InOrder(root->_right ); } } void _PrevOrder(Node* root) { if(root) { cout<<root->_data <<" "; _PrevOrder(root->_left ); _PrevOrder(root->_right ); } } //将一颗二叉搜索树变换成一个双向链表,但不创建任何新节点 //->终须线索化二叉搜索树(ToSort) /*Node* ToSort() { Node* prev = NULL; _ToSort(_root, prev); Node*head = _root; while (head&&head->_left) { head = head->_left; } return head; } void _ToSort(Node*cur, Node*&prev) { if (cur == NULL) { return; } _ToSort(cur->_left, prev); if (prev == NULL) { prev->_right = cur; } _ToSort(cur->_right, prev); */private: Node* _root; }; void TestBinaryTree(){ int a[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 }; BinaryTree<int> t(a, 10, '#'); t.PrevOrder(); t.PrevOrderNonR(); t.InOrder(); t.InOrderNonR(); t.PostOrder(); t.PostOrderNonR(); cout << t.LeafNum() << endl; //cout<<t.FindKLeve (3)<<endl; /*cout<<t.Size ()<<endl; cout<<t.Depth ()<<endl; BinaryTreeNode<int>* ret=t.Find (5); cout<<ret->_data <<endl; ret=t.Find (7); cout<<ret<<endl; t.LeveOder ();*/}
阅读全文
0 0
- 二叉树、二叉堆
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- Golang实现正方教务系统爬虫(一)
- VirtualBox中,虚拟系统文件VDI移动或者复制
- loadrunner Web_类函数之web_find()
- ImageLoder添加图片
- 进程与线程之间的关系
- 二叉树
- [bzoj-3713][PA2014]Iloczyn 题解
- Solr(四)——Java使用solrj管理solr集群
- Java8学习总结
- 大整数模板
- sleep() 和 wait() 有什么区别?
- Spring boot简单常用的注解
- IOS逆向--使用IDA的Patch更改汇编或二进制码并写入项目和deb重新打包
- 五、Spring Cloud系列:Eureka服务端与客户端常用配置