二叉树初步解析
来源:互联网 发布:开心的网络用语怎么说 编辑:程序博客网 时间:2024/05/29 19:32
二叉树
这两天说的数据结构都是一些简单 的结构,为什么说之前的数据结构都是简单的呢????
这是因为这些数据结构都是顺序结构 ,,,其中都没有使用到递归这种难度细数大的结构 。。。。。
之前说的广义表,,,,,,倒是使用到了递归,但是这只是最基本的结构,,,还不算太难。。。。
今天我们在这说的是 树这种数据结构,,,,,
什么是树呢?????
下面来看一幅图 !!!!!!!!!!
这就是个树
树是n(n>=0)个有限个数据的元素集合,形状像一颗倒过来的树。
关于树 中 为我们有这么一些概念 要知道
节点:结点包含数据和指向其它节点的指针。
根节点:树第一个结点称为根节点。
结点的度:结点拥有的子节点个数。
叶节点:没有子节点的节点(度为0)。
父子节点:一个节点father指向另一个节点child,则child为孩子节点,father为父亲节点 。
兄弟节点:具有相同父节点的节点互为兄弟节点。
节点的祖先:从根节点开始到该节点所经的所有节点都可以称为该节点的祖先。
子孙:以某节点为根的子树中任一节点都称为该节点的子孙。
根节点:树第一个结点称为根节点。
结点的度:结点拥有的子节点个数。
叶节点:没有子节点的节点(度为0)。
父子节点:一个节点father指向另一个节点child,则child为孩子节点,father为父亲节点 。
兄弟节点:具有相同父节点的节点互为兄弟节点。
节点的祖先:从根节点开始到该节点所经的所有节点都可以称为该节点的祖先。
子孙:以某节点为根的子树中任一节点都称为该节点的子孙。
这就是一颗树 中 该有 的元素 。。。。。。
关于这类树 我们设置节点时》》》》》》
需要设置的节点结构 为
节点 值 ;;;;
节点 的 子孩子。。。。。
因为这类树中的节点的子孩子的个数不确定 (可含有 0 ,一个 或者多个 )
我们可以Vector 容器来存储 节点的地址;;;;
在这里我们 可以 提供一种 普通树 节点的定义方法
template<class T>struct TreeNode {T _value;TreeNode<T> * _leftchild;//左孩子TreeNode<T> * _rightbrother;//右兄弟};
这类节点的定义方法为 ::::左孩子右兄弟节点。。。。。。
图形表示为:::
这棵树中 我们使用 _leftchild 来保存一个节点的孩子节点。。。。_rightbrother 保存一个节点的兄弟节点
通过这样来保存一棵树。。。。。。
这种树状结构在计算机领域中是十分常见的。。。。》》》就比如说
计算机的文件系统目录
这种就是使用这类树状结构来构造出来的。。。。
上面我们对于树的知识做了 一个好的开头,,,,,下面我们来看看今天的主要内容 二叉树
二叉树
何为二叉树?????
二叉树 就是 一个特殊的树》》》》》
只是每一个节点的孩子个数不能超过两个。。。。。
针对于这类二叉树。。。。我们有提出了两种别的概念 。。。。
那就是 完全二叉树 和 满二叉树
完全二叉树、、、满二叉树
完全二叉树、、、
一个树的前N-1层,,,都是满的(就是每个节点都含有两孩子节点),第N层节点从左到右分布 。。。。
满二叉树、、、
一棵树的N、、、、都是满的(每个节点都含有俩个节点)
也 就是说,,,,,满二叉树 一定是 完全二叉树 ,,,但是一个完全二叉树不一定是满二叉树。。。。
二叉树的结构
1、静态结构
我们会对 每一个节点 按层 进行标号
如下图所示 、、、、、
对于完全二叉树而言 、、、、、在这里我们的标号 有一个规律》》》》》
假设当前节点的下标为m
那么该 节点的左孩子的下标 为 m*2+1;
该节点的右孩子的下标为 m*2+2;
该节点的父节点的下标为 (m-1)/2;
对于静态的存储 我们可以使用广度优先遍历 (按层来遍历)的方式 来进行访问。。。。。
我们可以利用队列 先进先出的特点来 解决这个问题》》》》
如果一个节点的有子节点 ,,,那么将他的左右孩子 放到队列里,,,,读取该节点的值 ,,,再将他从队列中PoP出来,,,,这样 一直向后走,,,,,知道队列为空 。。。。
2、链式结构
所谓链式结构就是像链表一样 ,,,,进行存储。。。。
在这里主要有两种结构
1、二叉链 (节点包含两个指针:左孩子、右孩子)
2、三叉链(节点包含 三个指针 :左孩子,右孩子,父节点)
因为三叉链管理起来相对麻烦,,,所以我们一般使用二叉链
对一颗二叉树我们要实现的基本操作 都有:
构造函数、
拷贝构造、
赋值操作符重载、
析构函数、
求节点的个数、
求树的深度、
求叶子节点的个数、
求第K层节点的个数、、、
在这里的这些函数都要用到递归、、、、、才能更好的实现
#pragma once#include<iostream>#include<assert.h>using namespace std;#include<queue>template<class T>struct BinaryTreeNode{T _data;//存储数据BinaryTreeNode<T> * _left;//左节点BinaryTreeNode<T> * _right;//右节点BinaryTreeNode(const T& data):_data(data),_left(NULL),_right(NULL){}};//二r叉树结构template<class T>class BinaryTree{typedef BinaryTreeNode<T> Node;public:BinaryTree(T * arr,size_t size, const T & invalid = T()){assert(arr);size_t index=0 ;_root = _CreateTree(arr,size,invalid,index);}BinaryTree(const BinaryTree<T>& b){_root = _Copy(b._root);}BinaryTree<T> & operator=(const BinaryTree<T>& b){if(this != &b ){BinaryTree<T> tem(b);std::swap(tem._root ,_root);}return *this;}~BinaryTree(){Destroy();}void Destroy(){_Destroy(_root);}public:Node * _Copy(Node * root){if(root == NULL)return NULL;Node *cur = new Node(root->_data);cur->_left = _Copy(root->_left);cur->_right = _Copy(root->_right);return cur;}void _Destroy(Node * root){if(root ==NULL)return ;_Destroy(root->_left);_Destroy(root->_right);delete root;}//求节点个数size_t Size(){return _Size(_root);}//求深度size_t Depth(){return _Depth(_root);}//求叶子节点个数size_t GetLeafSize(){return _GetLeafSize(_root);}//求第K层节点的个数size_t GetKLevelSize(size_t K){//assert(K> 0 );//return _GetKLevelSize(_root,K);assert(K>0);size_t count = 0;size_t idex =1;_GetKLevelSize(_root,K,count,idex);return count;}//前序遍历void PreOrder(){_PreOrder(_root);cout<<endl;}//中序遍历void MidOrder(){_MidOrder(_root);cout<<endl;}//后续遍历void PostOrder(){_PostOrder(_root);cout<<endl;}//层序遍历void LevelOrder(){if(!_root)return ;queue<Node *> q ;q.push(_root);while(!q.empty()){Node * cur = q.front();cout<<cur->_data<<" ";q.pop();if(cur->_left){q.push(cur->_left);}if(cur->_right){q.push(cur->_right);}}cout<<endl;}protected:Node * _CreateTree(T *arr, size_t size, const T & invalid,size_t & idex){Node * newNode= NULL;if(idex <size &&arr[idex] != invalid ){newNode = new Node(arr[idex]);newNode->_left = _CreateTree(arr,size,invalid,++idex);newNode->_right = _CreateTree(arr,size,invalid,++idex);}return newNode;}size_t _GetLeafSize(Node * root){if(!root)return 0 ;if(!root->_left && ! root->_right)return 1;return _GetLeafSize(root->_left)+ _GetLeafSize(root->_right);}size_t _Size(Node * root){if(root ==NULL)return 0;return 1+_Size(root->_left)+_Size(root->_right);}size_t _Depth(Node * root){if(root == NULL)return 0 ;int left = _Depth(root->_left);int right = _Depth(root->_right);return left >right ? left+1:right+1;}size_t _GetKLevelSize(Node * root,size_t k){if(root == NULL )return 0;if(k == 1 )return 1;return _GetKLevelSize(root->_left,k-1) + _GetKLevelSize(root->_right,k-1);}void _GetKLevelSize(Node *root,const size_t K,size_t & count,size_t idex){if(root ==NULL)return ;if(idex == K){count++;return ;}_GetKLevelSize(root->_left,K,count,idex+1) ;_GetKLevelSize(root->_right,K,count,idex+1);}void _PreOrder(Node * root){if(root == NULL)return;cout<<root->_data<<" ";_PreOrder(root->_left);_PreOrder(root->_right);}void _MidOrder(Node * root){if(root == NULL)return;_MidOrder(root->_left);cout<<root->_data<<" ";_MidOrder(root->_right);}void _PostOrder(Node * root){if(root == NULL)return;_PostOrder(root->_left);_PostOrder(root->_right);cout<<root->_data<<" ";}protected:Node* _root;};void TestBinaryTree(){int array1[10] = {1, 2, 3, '#', '#', 4, '#' , '#', 5, 6};int array2[15] = {1,2,'#',3,'#','#',4,5,'#',6,'#',7,'#','#',8};BinaryTree<int> b1(array1,10,'#');b1.PreOrder();b1.MidOrder();b1.PostOrder();b1.LevelOrder();cout<<b1.Size()<<endl;cout<<b1.Depth()<<endl;cout<<b1.GetKLevelSize(1)<<endl;BinaryTree<int> b2(b1);b2.PreOrder();BinaryTree<int> b3(array2,15,'#');b2 = b3;b1.PreOrder();b2.PreOrder();b3.PreOrder();cout<<b3.GetKLevelSize(5)<<endl;}
0 0
- 二叉树初步解析
- 二叉树——Java初步实现
- 二叉树遍历解析
- 二叉树恢复解析
- 平衡二叉树解析
- 深入解析二叉树
- 二叉树遍历解析
- 解析平衡二叉树
- 解析线索二叉树
- 二叉树遍历解析
- 二叉搜索树简单解析
- 学习笔记:树和二叉树的初步学习1
- 学习笔记:树和二叉树的初步学习2
- 对二叉树的初步学习之递归的应用
- tomcat批处理文件初步解析
- java通信协议初步解析
- tomcat批处理文件初步解析
- ListView初步解析
- 改变多边形窗口的时机;SetWindowRgn;CreatePolygonRgn;POINT;PolyDraw
- ios9新特性之关键字
- Error:Execution failed for task ':app:transformClassesWithDexForDebug'.
- JAVA基本数据类型介绍
- leetcode-46-permutations 搜索
- 二叉树初步解析
- storm学习笔记 - 1(简介)
- Android自定ViewGroup实现流式布局
- 在 opengl 中画出三角形并用 shader 改变颜色
- javaIO RandomAccessFile
- 入职两个月的总结和反思
- 写一写R
- Caffe 源码 Makefile学习
- UML视频小总结(一)