树的定义
#include<iostream>
using namespace std;
typedef char ElemType;
typedef struct BiTNode{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
bool InitBiTree(BiTree& T); //初始化
bool InitBiTree(BiTree& T){
ElemType ch;
cin>>ch;
if(ch=='#'){
T = NULL;
}else{
T = (BiTNode*)malloc(sizeof(BiTNode));
T->data = ch;
InitBiTree(T->lchild);
InitBiTree(T->rchild);
}
}
求高度
int treeDepth(BiTree T); //计算树的深度
int treeDepth(BiTree T){
if(T==NULL) return 0;
int l = treeDepth(T->lchild);
int r = treeDepth(T->rchild);
return l>r?l+1:r+1;
}
int main(){
BiTree T;
InitBiTree(T);
cout<<treeDepth(T);
return 0;
}
先中后序遍历二叉树
void visit(BiTNode* p){
cout<<p->data<<" ";
}
void PreOrder(BiTree T){
if(T==NULL) return ;
visit(T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
void InOrder(BiTree T){
if(T==NULL) return ;
InOrder(T->lchild);
visit(T);
InOrder(T->rchild);
}
void PostOrder(BiTree T){
if(T==NULL) return ;
PostOrder(T->lchild);
PostOrder(T->rchild);
visit(T);
}
void tree(){
BiTree T;
InitBiTree(T);
//"先序遍历"
PreOrder(T);
cout<<endl;
//"中序序遍历"
InOrder(T);
cout<<endl;
//"后序遍历"//
PostOrder(T);
cout<<endl;
}
层次遍历
void LevelOrder(BiTree T){
LinkQueue Q;
InitQueue(Q);
BiTree p;
EnQueue(Q,T);
while(!QueueEmpty(Q)){
DeQueue(Q,p);
visit(p);
if(p->lchild!=NULL){
EnQueue(Q,p->lchild);
}
if(p->rchild!=NULL){
EnQueue(Q,p->rchild);
}
}
}
定义顺序存储的二叉树(从数组下标1开始存储)
typedef struct TreeNode {
int data; //结点中的数据元素
bool isEmpty; //结点是否为空
} TreeNode;
//初始化顺序存储的二叉树,所有结点标记为"空"
void InitSqBiTree (TreeNode t[], int length) {
for (int i=0; i<length; i++){
t[i].isEmpty=true;
}
}
int main(){
TreeNode t[100]; //定义一棵顺序存储的二叉树
InitSqBiTree(t, 100); //初始化为空树
//...
}
实现函数,找到结点 i 的父结点、左孩子、右孩子
若顺序二叉树从数组下标1开始存储结点,则:
● 结点 i 的父结点编号为 i/2
● 结点 i 的左孩子编号为 i*2
● 结点 i 的右孩子编号为 i*2+1
若顺序二叉树从数组下标0开始存储结点,则:
● 结点 i 的父结点编号为 [(i+1)/2] - 1
● 结点 i 的左孩子编号为 [(i+1)*2] - 1 = 2*i + 1
● 结点 i 的右孩子编号为 [(i+1)*2+1] - 1 = 2*i + 2
从数组下标1开始存储
//判断下标为 index 的结点是否为空
bool isEmpty(TreeNode t[], int length, int index){
if (index >= length || index < 1) return true; //下标超出合法范围
return t[index].isEmpty;
}
//找到下标为 index 的结点的左孩子,并返回左孩子的下标,如果没有左孩子,则返回 -1
int getLchild(TreeNode t[], int length, int index){
int lChild = index * 2; //如果左孩子存在,则左孩子的下标一定是 index * 2
if (isEmpty(t, length, lChild)) return -1; //左孩子为空
return lChild;
}
//找到下标为 index 的结点的右孩子,并返回右孩子的下标,如果没有右孩子,则返回 -1
int getRchild(TreeNode t[], int length, int index){
int rChild = index * 2 + 1; //如果右孩子存在,则右孩子的下标一定是 index * 2 + 1
if (isEmpty(t, length, rChild)) return -1; //右孩子为空
return rChild;
}
//找到下标为 index 的结点的父节点,并返回父节点的下标,如果没有父节点,则返回 -1
int getFather(TreeNode t[], int length, int index){
if (index == 1) return -1; //根节点没有父节点
int father = index / 2; //如果父节点存在,则父节点的下标一定是 index/2,整数除法会自动向下取整
if (isEmpty(t, length, father)) return -1;
return father;
}
从数组下标0开始存储
//判断下标为 index 的结点是否为空
bool isEmpty(TreeNode t[], int length, int index){
if (index >= length || index < 0) return true; //下标超出合法范围
return t[index].isEmpty;
}
//找到下标为 index 的结点的左孩子,并返回左孩子的下标,如果没有左孩子,则返回 -1
int getLchild(TreeNode t[], int length, int index){
int lChild = index * 2 + 1; //如果左孩子存在,则左孩子的下标一定是 index * 2
if (isEmpty(t, length, lChild)) return -1; //左孩子为空
return lChild;
}
//找到下标为 index 的结点的右孩子,并返回右孩子的下标,如果没有右孩子,则返回 -1
int getRchild(TreeNode t[], int length, int index){
int rChild = index * 2 + 2; //如果右孩子存在,则右孩子的下标一定是 index * 2 + 1
if (isEmpty(t, length, rChild)) return -1; //右孩子为空
return rChild;
}
//找到下标为 index 的结点的父节点,并返回父节点的下标,如果没有父节点,则返回 -1
int getFather(TreeNode t[], int length, int index){
if (index == 1) return -1; //根节点没有父节点
int father = (index + 1) / 2 - 1; //如果父节点存在,则父节点的下标一定是 index/2,整数除法会自动向下取整
if (isEmpty(t, length, father)) return -1;
return father;
}
实现先/中/后序遍历
//从下标为 index 的结点开始先序遍历
void PreOrderSqTree (TreeNode *t, int length, int index){
if (isEmpty(t, length, index)) //当前为空节点
return;
visitNode(t[index]); //访问结点
PreOrderSqTree(t, length, getLchild(t, length, index)); //先序遍历左子树
PreOrderSqTree(t, length, getRchild(t, length, index)); //先序遍历右子树
}
//从下标为 index 的结点开始中序遍历
void InOrderSqTree (TreeNode *t, int length, int index){
if (isEmpty(t, length, index)) //当前为空节点
return;
InOrderSqTree(t, length, getLchild(t, length, index)); //中序遍历左子树
visitNode(t[index]); //访问结点
InOrderSqTree(t, length, getRchild(t, length, index)); //中序遍历右子树
}
//从下标为 index 的结点开始后序遍历
void PostOrderSqTree (TreeNode *t, int length, int index){
if (isEmpty(t, length, index)) //当前为空节点
return;
PostOrderSqTree(t, length, getLchild(t, length, index)); //后序遍历左子树
PostOrderSqTree(t, length, getRchild(t, length, index)); //后序遍历右子树
visitNode(t[index]); //访问结点
}
int main(){
TreeNode t[100]; //定义一棵顺序存储的二叉树
InitSqBiTree(t, 100); //初始化为空树
//...在空二叉树中插入数据
//...略
InOrderSqTree (t, 100, 1); //从根节点1出发,进行中序遍历
双亲表示法 定义顺序树
#define MAX_TreeSize 100 //树中最多结点数
typedef struct {//树的结点定义
ElemType data;//数据元素
int parent;//双亲位置域
}PTNode;
typedef struct{ //树的类型定义
PTNode nodes [MAX_TreeSize];//双亲表示
int n;//结点数
}PTree;
“孩子表示法”,定义链式存储的树
//Child表示下一个孩子的信息
typedef struct Child{
int index; //孩子编号
struct Child * next; //下一个孩子
} Child;
//TreeNode用于保存结点信息
typedef struct TreeNode {
char data; //结点信息
Child * firstChild; //指向第一个孩子
} TreeNode;
TreeNode tree[10]; //定义一棵拥有10个结点的树(孩子表示法)