二叉树特点
- 每个父节点至多有两个子节点
- 非空二叉树中的叶子结点的数量等于双分支结点(度为2的结点)的数量加1.
- 二叉树的第i层上最多有2^(i-1)(i>=1)个节点。
- 高度(或深度)为i的二叉树最多有2^i-1(i>=1)个节点。也可以认为高度为i的二叉树有 2^i-1 个结点,那么该二叉树为满二叉树。
二叉树遍历
- 先序遍历(根左右)
- 中序遍历(左根右)
- 后序遍历(左右根)
代码(C++)
代码中对应的树
先序、中序、后序递归遍历
#include<iostream>
using namespace std;
//二叉树结点
typedef struct BINARYNODE
{
char ch;
BINARYNODE* lchild;
BINARYNODE* rchild;
}BinaryNode;
//先序遍历(根左右)
void preOrder(BinaryNode* root)
{
if (root == NULL)
{
return;
}
//输出根结点
cout << root->ch;
//遍历左子树
preOrder(root->lchild);
//遍历右子树
preOrder(root->rchild);
}
//中序遍历(左根右)
void midOrder(BinaryNode* root)
{
if (root == NULL)
{
return;
}
//遍历左子树
midOrder(root->lchild);
//输出根结点
cout << root->ch;
//遍历右子树
midOrder(root->rchild);
}
//后序遍历(左右根)
void postOrder(BinaryNode* root)
{
if (root == NULL)
{
return;
}
//遍历左子树
postOrder(root->lchild);
//遍历右子树
postOrder(root->rchild);
//输出根结点
cout << root->ch;
}
求叶子结点数目(递归)
void LeafNum(BinaryNode* root, int& num)
{
if (root == NULL) return;
if (root->lchild == NULL && root->rchild == NULL)
{
num++;
}
//遍历左子树
LeafNum(root->lchild, num);
//遍历右子树
LeafNum(root->rchild, num);
}
求二叉树的高度
//求二叉树高度
int TreeHight(BinaryNode* root)
{
if (root == NULL) return 0;
int leftHight = TreeHight(root->lchild);
int rightHight = TreeHight(root->rchild);
TreeHight(root->rchild);
return leftHight > rightHight ? leftHight + 1 : rightHight + 1;
}
拷贝二叉树
//拷贝二叉树
BinaryNode* CopyBinaryTree(BinaryNode* root)
{
if (root == NULL) return NULL;
//拷贝左子树
BinaryNode* lchild = CopyBinaryTree(root->lchild);
//拷贝右子树
BinaryNode* rchild = CopyBinaryTree(root->rchild);
BinaryNode* newnode = (BinaryNode*)malloc(sizeof(BinaryNode));
if (newnode != NULL)
{
newnode->ch = root->ch;
newnode->lchild = root->lchild;
newnode->rchild = root->rchild;
}
return newnode;
}
释放二叉树
//释放二叉树
void FreeSapce_BinaryTree(BinaryNode* root)
{
if (root == NULL)
return;
FreeSapce_BinaryTree(root->lchild);
FreeSapce_BinaryTree(root->rchild);
free(root);
}
测试
//创建二叉树
void CreateBinaryTree()
{
//创建二叉树的结点
BinaryNode node1 = { 'A',NULL,NULL };
BinaryNode node2 = { 'B',NULL,NULL };
BinaryNode node3 = { 'C',NULL,NULL };
BinaryNode node4 = { 'D',NULL,NULL };
BinaryNode node5 = { 'E',NULL,NULL };
BinaryNode node6 = { 'F',NULL,NULL };
BinaryNode node7 = { 'G',NULL,NULL };
BinaryNode node8 = { 'H',NULL,NULL };
//连接二叉树结点构成二叉树
node1.lchild = &node2;
node1.rchild = &node6;
node2.rchild = &node3;
node3.lchild = &node4;
node3.rchild = &node5;
node6.rchild = &node7;
node7.lchild = &node8;
//先序遍历
preOrder(&node1);
cout << endl;
//中序遍历
midOrder(&node1);
cout << endl;
//后序遍历
postOrder(&node1);
cout << endl;
//求叶子结点数目
int num = 0;
LeafNum(&node1, num);
cout << "叶子结点数目:" << num << endl;
//求二叉树的高度
int hight = TreeHight(&node1);
cout << "二叉树的高度:" << hight << endl;
//拷贝二叉树
preOrder(&node1);
cout << endl;
cout << "拷贝后的二叉树:" << endl;
preOrder(newnode);
cout << endl;
//释放二叉树
FreeSapce_BinaryTree(newnode);
}
二叉树的非递归遍历(链式栈)
链式栈(用企业链表实现)
LinkStack.h文件
#pragma once
#include<stdio.h>
#include<stdlib.h>
//链式栈的结点
typedef struct LINKNODE
{
LINKNODE* next;
}LinkNode;
//链式栈
typedef struct LINKSTACK
{
LinkNode head;
int size;
}LinkStack;
//初始化栈
LinkStack* Init_LinkStack();
//入栈
void Push_LinkStack(LinkStack* stack, LinkNode* data);
//出栈
void Pop_LinkStack(LinkStack* stack);
//返回栈顶元素
LinkNode* Top_LinkStack(LinkStack* stack);
//返回栈中元素个数
int Size_LinkStack(LinkStack* stack);
//清空栈
void Clear_LinkStack(LinkStack* stack);
//销毁栈
void FreeSpace_LinkStack(LinkStack* stack);
LinkStack.cpp文件
#include "LinkStack.h"
//初始化栈
LinkStack* Init_LinkStack()
{
LinkStack* stack = (LinkStack*)malloc(sizeof(LinkStack));
if (stack != NULL)
{
stack->head.next = NULL;
stack->size = 0;
}
return stack;
}
//入栈
void Push_LinkStack(LinkStack* stack, LinkNode* data)
{
if (stack == NULL || data == NULL)
{
return;
}
data->next = stack->head.next;
stack->head.next = data;
stack->size++;
}
//出栈
void Pop_LinkStack(LinkStack* stack)
{
if (stack == NULL || stack->size == 0) return;
stack->head.next = stack->head.next->next;
stack->size--;
}
//返回栈顶元素
LinkNode* Top_LinkStack(LinkStack* stack)
{
if (stack == NULL || stack->size == 0) return NULL;
return stack->head.next;
}
//返回栈中元素个数
int Size_LinkStack(LinkStack* stack)
{
if (stack == NULL) return -1;
return stack->size;
}
//清空栈
void Clear_LinkStack(LinkStack* stack)
{
if (stack == NULL || stack->size == 0) return;
stack->head.next = NULL;
stack->size = 0;
}
//销毁栈
void FreeSpace_LinkStack(LinkStack* stack)
{
if (stack == NULL) return;
free(stack);
}
非递归遍历测试
#include<iostream>
using namespace std;
#include"LinkStack.h"
#define MY_FALSE 0
#define MY_TRUE 1
//二叉树结点
typedef struct BINARYNODE
{
char ch;
BINARYNODE* lchild;
BINARYNODE* rchild;
}BinaryNode;
typedef struct BITREESTACKNODE
{
LinkNode node;
BinaryNode* root;
int flag;
}BiTreeStackNode;
//创建栈中的结点
BiTreeStackNode* CreateBiTreeStackNode(BinaryNode* node, int flag)
{
BiTreeStackNode* newnode = (BiTreeStackNode*)malloc(sizeof(BiTreeStackNode));
if (newnode != NULL)
{
newnode->root = node;
newnode->flag = flag;
}
return newnode;
}
//非递归遍历
void NonRecursion(BinaryNode* root)
{
//创建栈
LinkStack* stack = Init_LinkStack();
//将根结点压入栈
Push_LinkStack(stack, (LinkNode*)CreateBiTreeStackNode(root, MY_FALSE));
while (Size_LinkStack(stack) > 0)
{
BiTreeStackNode *node = (BiTreeStackNode*)Top_LinkStack(stack);
Pop_LinkStack(stack);
if (node->root == NULL)
{
continue;
}
if (node->flag == MY_TRUE)
{
cout << node->root->ch;
}
else
{
//将当前结点的右节点压入栈中
Push_LinkStack(stack, (LinkNode*)CreateBiTreeStackNode(node->root->rchild, MY_FALSE));
//将当前结点的左节点压入栈中
Push_LinkStack(stack, (LinkNode*)CreateBiTreeStackNode(node->root->lchild, MY_FALSE));
//修改当前结点的标志
node->flag = MY_TRUE;
//将当前结点压入栈
Push_LinkStack(stack, (LinkNode*)node);
}
}
}
//创建二叉树
void CreateBinaryTree()
{
//创建二叉树的结点
BinaryNode node1 = { 'A',NULL,NULL };
BinaryNode node2 = { 'B',NULL,NULL };
BinaryNode node3 = { 'C',NULL,NULL };
BinaryNode node4 = { 'D',NULL,NULL };
BinaryNode node5 = { 'E',NULL,NULL };
BinaryNode node6 = { 'F',NULL,NULL };
BinaryNode node7 = { 'G',NULL,NULL };
BinaryNode node8 = { 'H',NULL,NULL };
//连接二叉树结点构成二叉树
node1.lchild = &node2;
node1.rchild = &node6;
node2.rchild = &node3;
node3.lchild = &node4;
node3.rchild = &node5;
node6.rchild = &node7;
node7.lchild = &node8;
NonRecursion(&node1);
}
int main()
{
CreateBinaryTree();
system("pause");
return 0;
}