树的组成
节点的度:节点拥有的子树的数目。
叶子:度为零的节点。
分支节点:度不为零的节点。
树的度:树中节点的最大的度。
层次:根节点的层次为1,其余节点的层次等于该节点的双亲节点加1。
树的高度:树中节点的最大层次。
无序数:如果树中节点的各子树之间的次序是不重要的,可以交换位置。
有序数:如果树中结点的各子树的次序是重要的,不可以交换位置。
森林:0个或多个不相交的树组成。对森林加上一个跟,森林即成为树;删去跟,树即成为森林。
二叉树
二叉树是每个节点最多有两个子树的树结构。它有五种基本形态:二叉树可以是空集;根可以有空的左子树或右子树;或者左、右子树皆为空。
把每一个节点包装成一个结构体,并含有指向其左右子节点的成员。
typedef struct BinaryTreeNode
{
int val;
struct BinaryTreeNode* _left;
struct BinaryTreeNode* _right;
}TNode;
二叉树的三种遍历
前序:(先根遍历)根->左子树->右子树
中序:左子树->根->右子树
后序:左子树->右子树->根
// 测试数据
void test2()
{
BTNode* A = CreatNode(1);
BTNode* B = CreatNode(2);
BTNode* C = CreatNode(3);
BTNode* D = CreatNode(4);
BTNode* E = CreatNode(5);
A->_left = B;
A->_right = C;
B->_left = D;
B->_right = E;
prevorder(A);
cout << endl;
Inorder(A);
cout << endl;
postorder(A);
Destory(A);
}
void Destory(BTNode* root)
{
if (root == nullptr)
{
return;
}
Destory(root->_left);
Destory(root->_right);
root->_left = nullptr;
root->_right = nullptr;
delete root;
}
BTNode* CreatNode(int val)
{
BTNode* p = new BTNode();
if (p == NULL)
{
return NULL;
}
p->_val = val;
p->_left = nullptr;
p->_right = nullptr;
return p;
}
//前序遍历
void prevorder(BTNode* root)
{
if (root == nullptr)
{
cout << "nullptr" << " ";
return;
}
cout << root->_val << " ";
prevorder(root->_left);
prevorder(root->_right);
}
结果:1 2 4 nullptr nullptr 5 nullptr nullptr 3 nullptr nullptr
// 中序遍历
void Inorder(BTNode* root)
{
if (root == nullptr)
{
cout << "nullptr" << " ";
return;
}
Inorder(root->_left);
cout << root->_val << " ";
Inorder(root->_right);
}
结果:nullptr 4 nullptr 2 nullptr 5 nullptr 1 nullptr 3 nullptr
//后序遍历
void postorder(BTNode* root)
{
if (root == nullptr)
{
cout << "nullptr" << " ";
return;
}
postorder(root->_left);
postorder(root->_right);
cout << root->_val << " ";
}
结果:nullptr nullptr 4 nullptr nullptr 5 2 nullptr nullptr 3 1
层序遍历
输出顺序为1 2 3 4 5
需要一个队列,实现先进先出,头删为插。
// 层序遍历
typedef struct Queue
{
struct Queue* _next;
BTNode* _root;
}Queue;
Queue* NewNode()
{
Queue* p = new Queue();
if (p == NULL)
{
return nullptr;
}
p->_next = nullptr;
p->_root = nullptr;
return p;
}
Queue* Findtail(Queue* head)
{
Queue* tail = head;
while (tail->_next != nullptr)
{
tail = tail->_next;
}
return tail;
}
void push_back(BTNode* root,Queue*head)
{
Queue* tail = Findtail(head);
tail->_next = NewNode();
tail->_next->_root = root;
}
void pop_front(Queue*head)
{
Queue* tmp = head->_next->_next;
delete head->_next;
head->_next = tmp;
}
void Leverorder(BTNode*root)
{
Queue* head = NewNode(); // 给一个空的头节点
push_back(root,head);
while (head->_next != nullptr)
{
BTNode* firstnode = head->_next->_root;
if (firstnode != nullptr)
{
cout << firstnode->_val << " ";
push_back(firstnode->_left, head);
push_back(firstnode->_right, head);
}
else
{
cout << "nullptr" << " ";
}
pop_front(head); // 删的是头的下一个真实存储root的节点
}
}
结果:1 2 3 4 5 nullptr nullptr nullptr nullptr nullptr nullptr
//求树的元素的个数
void Treesize(BTNode* root, int&size)
{
if (root == nullptr)
{
return;
}
size++;
Treesize(root->_left, size);
Treesize(root->_right, size);
}
//求树的高度
int Treehigh(BTNode*root)
{
if (root == nullptr)
{
return 0;
}
int high = Treehigh(root->_left) > Treehigh(root->_right) ? Treehigh(root->_left) : Treehigh(root->_right);
return high + 1;
}
//叶子节点的个数
int sizeleaf(BTNode* root)
{
if (root == nullptr)
{
return 0;
}
int a = 0;
if (root->_left == nullptr && root->_right == nullptr)
{
a = 1;
}
return a + sizeleaf(root->_left) + sizeleaf(root->_right);
}
//第lay层节点的个数
int Nodenum(BTNode*root,int lay)
{
if (root == nullptr)
{
return 0;
}
if (lay == 1)
{
return 1;
}
return Nodenum(root->_left, lay - 1) + Nodenum(root->_right, lay - 1);
}
平衡二叉树
平衡二叉树搜索树:又被称为AVL(Adelson-Velsky and Landis)树
且具有以下性质:它是一颗空树或者它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一颗平衡二叉树。
如何判断是否是平衡二叉树
//判断平衡二叉树
bool Isbalence(BTNode*root,int&high)
{
if (root == nullptr) // 当到达树低的时候,开始返回
{
high = 0;
return true;
}
else
{
int lefthigh = 0;
if (Isbalence(root->_left, lefthigh) == false) // 判断左子树是否是平衡二叉树
{
return false;
}
int righthigh = 0;
if (Isbalence(root->_right, righthigh) == false) //判断右子树是否是平衡二叉树
{
return false;
}
if (abs(lefthigh - righthigh) > 1) //判断该树是否是平衡二叉树
{
return false;
}
// 但凡有一个false结果就是false
high = 1+(lefthigh > righthigh ? lefthigh : righthigh);
return true;
}
}