暂时略
图形表示法:直观清晰易于理解。
广义表表示法:不常用。
左孩子右兄弟表示法:可以将多叉树转化为二叉树的一种表示方法,而二叉树更适合计算机表示。(也就是说一般遇到多叉树,转化成二叉树)
略
用一个数组来存储二叉树,结合二叉树的性质,可以保存树的结点之间的关系。最适合完全二叉树和满二叉树,如果是一般二叉树,将导致存储空间浪费,最坏情况下是一颗右斜树。
二叉链表示法:包含lchild、data、rchild
三叉链表示法:包含lchild、data、rchild和parent。这种表示方法记录了各个结点的父结点位置,增加了开销,但是便于查找父结点。
双亲表示法:包含data、parent、LRtag,数据域、父结点位置、是左孩子还是右孩子。实际开发中如果树不是太复杂,就选择这种表示方法。
BitNode.h
#ifndef _BITNODE_H_
#define _BITNODE_H_
//用二叉链表示法表示树的数据结构
typedef struct BitNode
{
char data;
struct BitNode *lchild, *rchild;//左右孩子指针
}BitNode;
//typedef struct BitNode* BiTree;
void preOrder(BitNode *T);
void inOrder(BitNode *T);
void lastOrder(BitNode *T);
int getLeafNum(BitNode *T);
int Depth(BitNode *T);
#endif // !_BITNODE_H_
Operator.cpp
#include "BitNode.h"
#include
void preOrder(BitNode *T)
{
if (T == NULL)
return;
printf("%c", T->data);//输出根节点的值
//遍历左子树
if (T->lchild != NULL)
preOrder(T->lchild);
//遍历右子树
if (T->rchild != NULL)
preOrder(T->rchild);
}
void inOrder(BitNode *T)
{
if (T == NULL)
return;
//遍历左子树
if (T->lchild != NULL)
inOrder(T->lchild);
printf("%c", T->data);//输出根节点的值
//遍历右子树
if (T->rchild != NULL)
inOrder(T->rchild);
}
void lastOrder(BitNode *T)
{
if (T == NULL)
return;
//遍历左子树
if (T->lchild != NULL)
lastOrder(T->lchild);
//遍历右子树
if (T->rchild != NULL)
lastOrder(T->rchild);
printf("%c", T->data);//输出根节点的值
}
int getLeafNum(BitNode *T)
{
static int sum = 0;
if (T == NULL)
return 0;
if (T->lchild == NULL && T->rchild == NULL)//左右孩子均为空,就是叶子节点
sum++;//叶子节点数+1
getLeafNum(T->lchild);//获取左子树的叶子节点数
getLeafNum(T->rchild);
return sum;
}
int Depth(BitNode *T)
{
int depth = 0;
int ldepth = 0, rdepth = 0;
if (T == NULL)
return 0;
ldepth = Depth(T->lchild);
rdepth = Depth(T->rchild);
return 1 + (ldepth > rdepth ? ldepth : rdepth);
}
main.cpp
#include
#include
#include
#include "BitNode.h"
int main()
{
BitNode nodeA, nodeB, nodeD, nodeF, nodeI, nodeL;//创建6个结点
//将结点空间初始化为空
memset(&nodeA, 0, sizeof(BitNode));
memset(&nodeB, 0, sizeof(BitNode));
memset(&nodeD, 0, sizeof(BitNode));
memset(&nodeF, 0, sizeof(BitNode));
memset(&nodeI, 0, sizeof(BitNode));
memset(&nodeL, 0, sizeof(BitNode));
//给结点赋值
nodeA.data = 'A';
nodeB.data = 'B';
nodeD.data = 'D';
nodeF.data = 'F';
nodeI.data = 'I';
nodeL.data = 'L';
//存储结点之间的关系
nodeA.lchild = &nodeB;
nodeA.rchild = &nodeD;
nodeB.rchild = &nodeF;
nodeF.lchild = &nodeL;
nodeD.lchild = &nodeI;
printf("二叉树构建成功!\n");
printf("先序遍历:");
preOrder(&nodeA);
printf("\n中序遍历:");
inOrder(&nodeA);
printf("\n后序遍历:");
lastOrder(&nodeA);
printf("\n");
printf("叶子结点个数:%d\n", getLeafNum(&nodeA));
printf("树的高度:%d\n", Depth(&nodeA));
system("pause");
return 0;
}
linkstack.h
#ifndef _LINKSTACK_H_
#define _LINKSTACK_H_
//二叉树的结点结构
typedef struct BitNode
{
char data;//数据类型为char
struct BitNode *lchild, *rchild;
}BitNode;
//栈的结点结构
typedef struct Node *pNode;
typedef struct Stack *LinkStack;
struct Node //数据结点
{
BitNode * data; //数据,BitNode类型的指针
pNode next;//指针
};
struct Stack
{
pNode top; //栈顶元素指针
int size; //栈大小
};
LinkStack Create();//创建栈
int IsEmpty(LinkStack lstack);//判断栈是否为空
int Push(LinkStack lstack, BitNode *val);//压栈
pNode getTop(LinkStack lstack);//获取栈顶元素
pNode Pop(LinkStack lstack);//弹出栈顶元素
#endif // !_LINKSTACK_H_
linkstack.cpp
#include "linkstack.h"
#include
#include
LinkStack Create()//创建栈实际上就是先创建一个栈的头结点
{
LinkStack lstack = (LinkStack)malloc(sizeof(struct Stack));
if (lstack != NULL)
{
lstack->top = NULL;
lstack->size = 0;
}
return lstack;
}
int IsEmpty(LinkStack lstack)
{
if (lstack->top == NULL || lstack->size == 0)
return 1;
return 0;
}
int Push(LinkStack lstack, BitNode *val)
{
pNode node = (pNode)malloc(sizeof(struct Node));//为val元素分配一个新的节点
if (node != NULL)
{
node->data = val;
node->next = getTop(lstack);
lstack->top = node;
lstack->size++;
}
return 1;
}
pNode getTop(LinkStack lstack)//获取栈顶元素
{
if (lstack->size != 0)
return lstack->top;
return NULL;
}
pNode Pop(LinkStack lstack)
{
if (IsEmpty(lstack))
{
return NULL;
}
pNode node = lstack->top; //node指向栈顶元素
lstack->top = lstack->top->next; //top指向下一个元素
lstack->size--;
return node;
}
main.cpp
#include
#include
#include
#include "linkstack.h"
//寻找遍历起始点
BitNode * GoFarLeft(BitNode * T, LinkStack ls)
{
if (T == NULL)
return NULL;
while (T->lchild != NULL)//左子树不为空,就一直向下寻找
{
Push(ls, T);
T = T->lchild;
}
return T;
}
//非递归中序遍历函数
void MyOrder(BitNode * T)
{
LinkStack ls = Create();
BitNode * t = GoFarLeft(T, ls);//寻找遍历的起始点
while (t != NULL)
{
printf("%c", t->data);//打印起始结点的值
if (t->rchild != NULL)
t = GoFarLeft(t->rchild, ls);//寻找右子树中的起始点
else if (!IsEmpty(ls))//如果栈不为空
{
t = getTop(ls)->data;//回退到栈顶元素结点
Pop(ls);//栈顶元素弹出
}
else
t = NULL;
}
}
int main()
{
BitNode nodeA, nodeB, nodeD, nodeF, nodeI, nodeL;
memset(&nodeA, 0, sizeof(BitNode));
memset(&nodeB, 0, sizeof(BitNode));
memset(&nodeD, 0, sizeof(BitNode));
memset(&nodeF, 0, sizeof(BitNode));
memset(&nodeI, 0, sizeof(BitNode));
memset(&nodeL, 0, sizeof(BitNode));
//给结点赋值
nodeA.data = 'A';
nodeB.data = 'B';
nodeD.data = 'D';
nodeF.data = 'F';
nodeI.data = 'I';
nodeL.data = 'L';
//存储结点之间的逻辑关系
nodeA.lchild = &nodeB;
nodeA.rchild = &nodeD;
nodeB.rchild = &nodeF;
nodeF.lchild = &nodeL;
nodeD.lchild = &nodeI;
printf("构建二叉树成功!\n");
printf("非递归中序遍历:\n");
MyOrder(&nodeA);
printf("\n");
system("pause");
return 0;
}