基本概念梳理
- 孩子:子结点
- 双亲:父节点
- 度:有多少个子结点
- 有序树:固定的排列的树
- 无序树:排列与顺序无关的树
- 二叉树:所有结点小于等于2的树
需要实现的方法
#pragma once #ifndef TREE_H #define TREE_H class Tree { public: Tree(int size,int *pRoot);//创建树 ~Tree();//销毁树 int *SearchNode(int nodeIndex);//根据索引寻找结点 bool AddNode(int nodeIndex, int direction, int *pNode);//添加结点 bool DeleteNode(int nodeIndex, int *pNode);//删除结点 void TreeTraverse();//遍历 private: int *m_pTree; int m_iSize; }; #endif // !TREE_H
1.创建树
传入数组容量和根节点地址
m_iSize和m_pTree初始化
将数组都置为0初始化
pRoot指向的内存单元的树值赋值数组首元素(根元素)
Tree::Tree(int size, int *pRoot) { m_iSize = size; m_pTree = new int[m_iSize]; for (int i = 0; i < m_iSize; i++) { m_pTree[i] = 0; } m_pTree[0] = *pRoot; }
2.销毁树
删除指针并置空
Tree::~Tree() { delete []m_pTree; m_pTree = NULL; }
3.根据索引寻找结点
先判断索引的合法性,索引不能小于0或者大于等于长度
传入数组的值不能等于0
返回该数组地址
int *Tree::SearchNode(int nodeIndex) { if (nodeIndex<0 || nodeIndex>=m_iSize) { return NULL; } if (m_pTree[nodeIndex] == 0) { return NULL; } return &m_pTree[nodeIndex]; }
4.添加结点
判断索引合法性,和3.一样
direction = 0代表添加左子节点,direction = 1代表添加右子节点
左子节点 = 2*索引+1;右子节点 = 2*索引+2
下图可以验证
继续判断索引的合法性,左子节点和右子节点同样不能小于0或者大于等于数组长度
最后将*pNode赋值给子节点
bool Tree::AddNode(int nodeIndex, int direction, int *pNode) { if (nodeIndex<0 || nodeIndex >= m_iSize) { return false; } if (m_pTree[nodeIndex] == 0) { return false; } if (direction == 0) { //nodeIndex * 2 + 1<0可以省略 if (nodeIndex * 2 + 1<0 || nodeIndex * 2 + 1 >= m_iSize) { return false; } //判断是否有左子节点 if (m_pTree[nodeIndex * 2 + 1] != 0) { return false; } m_pTree[nodeIndex * 2 + 1] = *pNode; } if (direction == 1) { //nodeIndex * 2 + 2<0可以省略 if (nodeIndex * 2 + 2<0 || nodeIndex * 2 + 2 >= m_iSize) { return false; } //判断是否有左子节点 if (m_pTree[nodeIndex * 2 + 2] != 0) { return false; } m_pTree[nodeIndex * 2 + 2] = *pNode; } return true; }
5.删除结点
判断索引和数组值的合法性
将*pNode接收删除的对应索引的数组
将该索引数组置为0,结点值等于0代表删除
返回正确结果
bool Tree::DeleteNode(int nodeIndex, int *pNode) { if (nodeIndex<0 || nodeIndex >= m_iSize) { return false; } if (m_pTree[nodeIndex] == 0) { return false; } *pNode = m_pTree[nodeIndex]; m_pTree[nodeIndex] = 0; return true; }
6.遍历
没啥好说的
void Tree::TreeTraverse() { for (int i = 0; i < m_iSize; i++) { cout << m_pTree[i] << " "; } }