顺序二叉树
Binary Tree
#include<iostream> #include<math.h> using namespace std; #define MAXSIZE 100 enum ECCHILDSIGN //节点标记 { E_root, //树根 E_ChildLeft, //左孩子 E_ChildRight //右孩子 }; template<typename T> struct BinaryTreeNode { T data; //数据域 bool isValid; //该节点是否有效以应对非完全二叉树(只有保存了实际节点数据节点才是有效的) }; //二叉树的定义 template<typename T> class BinaryTree { public: BinaryTree() //构造函数 { for(int i = 0; i < MAXSIZE; ++i) //注意这里数组大小为 MAXSIZE + 1 { SqBiTree[i].isValid = false; //开始的时候节点无效 } } ~BinaryTree(){} //析构函数不需要做什么 public: //创建一个树节点 int CreateNode(int parindex, ECCHILDSIGN pointSign, const T& e); //获取父节点的下标 int getParentIdx(int sonindex) { if(ifValidRangeIdx(sonindex) == false) //位置不合理 { return -1; } if(SqBiTree[sonindex].isValid == false) //不是个合理节点 { return -1; } return int(sonindex / 2); } //获取某个节点所在的高度,根据性质:具有n(n > 0)个节点的完全二叉树的高度 log(n + 1)向上取整 或者是log(n)向下取整 + 1 int getPointLevel(int index) { if(ifValidRangeIdx(index) == false) //位置不合理 { return -1; } if(SqBiTree[index].isValid == false) //不是个合理节点 { return -1; } //采用计算公式: log(n)向下取整 + 1 int level = int(log(index) / log(2)) +1;//c++中的log(n)函数是以 e 为底 return level; } //获取二叉树的深度 int GetLevel() { if(SqBiTree[1].isValid == false) //没根 { return 0; } int i; for(i = MAXSIZE; i >= 1; --i) { if(SqBiTree[i].isValid == true) { break; } } return getPointLevel(i); } //判断是否是个完全二叉树 bool ifComplateBT() { if(SqBiTree[1].isValid == false) //没根 { return false; } int i; for(i = MAXSIZE; i >= 1; --i) { if(SqBiTree[i].isValid == true) break; } for(int k = 1; k <= i; ++k) { if(SqBiTree[k].isValid == false) { return false; } } return true; } //前序遍历二叉树,其他遍历的方式在二叉树的链式存储中在详细书写 void preOrder() { if(SqBiTree[1].isValid == false) //没根 { return ; } preOrder(1); //根节点的数组下标是1, 所以这里把根的下标传递进去 } void preOrder(int index) { if(ifValidRangeIdx(index) == false) //位置不合理 { return ; } if(SqBiTree[index].isValid == false) //不是个合理节点 { return ; } //根左右 cout << (char)SqBiTree[index].data << " "; //输出节点数据域的值 preOrder(2 * index); //递归方式遍历左子树 preOrder(2 * index + 1); //递归方式遍历右子树 } private: bool ifValidRangeIdx(int index) //是否是一个有效的数组下标值 { //位置必须合理 if(index < 1 || index > MAXSIZE) //[0]号位置不用 return false; return true; } private: BinaryTreeNode<T> SqBiTree[MAXSIZE + 1]; //存储二叉树节点的数组,下标为0不使用 }; //创建一个树节点 template<typename T> int BinaryTree<T>::CreateNode(int parindex, ECCHILDSIGN pointSign, const T& e) { //参数一:父节点所在的数组下标 //参数二:标记所创建的是树根,左孩子,右孩子。 //参数三: 插入的数据节点的元素值 if(pointSign != E_root) //非根节点,则一定是子节点,要求parindex一定是个合理值 { if(ifValidRangeIdx(parindex) == false) //位置不合理 { return -1; } if(SqBiTree[parindex].isValid == false) //不是个合理节点 { return -1; } } int index = -1; if( pointSign == E_root ) { index = 1; //根节点固定存储在下标为 1 的位置 } else if(pointSign == E_ChildLeft) //左孩子 { //创建的是左孩子节点,节点 i 的左孩子 节点的下标是 2i index = 2 * parindex; if(ifValidRangeIdx(index) == false) //位置不合理 { return -1; } } else { //创建的是右孩子节点,节点 i 的右孩子 节点的下标是 2i + 1 index = 2 * parindex + 1; if(ifValidRangeIdx(index) == false) //位置不合理 { return -1; } } SqBiTree[index].data = e; SqBiTree[index].isValid = true; //标记该下标中有有效数据 return index; } int main() { BinaryTree<int> mytree; //创建一个二叉树 int indexRoot = mytree.CreateNode(-1,E_root,'A'); //创建数根节点 int indexNodeB = mytree.CreateNode(indexRoot, E_ChildLeft,'B'); //创建左子节点 int indexNodeC = mytree.CreateNode(indexRoot, E_ChildRight, 'C');//创建右子节点 int indexNodeD = mytree.CreateNode(indexNodeB, E_ChildLeft,'D'); //创建左子节点 int indexNodeE = mytree.CreateNode(indexNodeC, E_ChildRight, 'E');//创建右子节点 int iParentIndexE = mytree.getParentIdx(indexNodeE); //获取某个节点的父节点下标 cout << "节点E的父节点的下标是: " << iParentIndexE << endl; int iLevel = mytree.getPointLevel(indexNodeD); //获取某个节点所在的高度 cout << "节点D所在的高度是: " << iLevel << endl; iLevel = mytree.getPointLevel(indexNodeE); //获取某个节点所在的高度 cout << "节点E所在的高度是: " << iLevel << endl; cout << "二叉树的深度是: " << mytree.GetLevel() << endl; cout << "二叉树是完全二叉树吗? " << mytree.ifComplateBT() << endl; cout << "------------------" << endl; cout << "前序遍历序列为: "; mytree.preOrder(); //前序遍历 cout << endl; return 0; }
欢迎大家指出博文中的错误哦。

浙公网安备 33010602011771号