树的相关基本知识
1
1.1双亲表示法: 大话数据结构 p156
data|parent
#define MAX_TREE_SIZE 100
typedef struct PTNode{ 结点结构
int data; 结点数据
int parent; 双亲位置
}PTNode;
1.1双亲表示法: 大话数据结构 p156
data|parent
#define MAX_TREE_SIZE 100
typedef struct PTNode{ 结点结构
int data; 结点数据
int parent; 双亲位置
}PTNode;
typedef struct{ 树结构
PTNode nodes[MAX_TREE_SIZE]; 结点数组
int r, n; 根的位置和结点数
}PTree;
PTNode nodes[MAX_TREE_SIZE]; 结点数组
int r, n; 根的位置和结点数
}PTree;
1.2孩子表示法:
孩子链表的孩子结点:child|next
表头数组的表头结点;data|firstchild
typedef struct CTNode{ 孩子结点
int child;
struct CTNode *next;
}*ChildPtr;
typedef struct{ 表头结构
int data;
ChildPtr firstchild;
}CTBox;
typedef struct{ 树结构
CTBox nodes[MAX_TREE_SIZE]; 结点数组
int r, n; 根的位置和结点数
}CTree;
孩子链表的孩子结点:child|next
表头数组的表头结点;data|firstchild
typedef struct CTNode{ 孩子结点
int child;
struct CTNode *next;
}*ChildPtr;
typedef struct{ 表头结构
int data;
ChildPtr firstchild;
}CTBox;
typedef struct{ 树结构
CTBox nodes[MAX_TREE_SIZE]; 结点数组
int r, n; 根的位置和结点数
}CTree;
1.3孩子兄弟表示法:
data|firstchild|rightchild
typedef struct CSNode{
int data;
struct CSNode *firstchild, *rightsib;
}CSNode, *CSTree;
data|firstchild|rightchild
typedef struct CSNode{
int data;
struct CSNode *firstchild, *rightsib;
}CSNode, *CSTree;
2
2.1二叉链表:
lchild|data|rchild
typedef struct BiTNode{ 结点结构
int data; 结点数据
struct BiTNode *lchild, *rchild; 左右孩子指针
}BiTNode, *BiTree;
2.1二叉链表:
lchild|data|rchild
typedef struct BiTNode{ 结点结构
int data; 结点数据
struct BiTNode *lchild, *rchild; 左右孩子指针
}BiTNode, *BiTree;
2.2三叉链表:
lchild|data|rchild|parent
lchild|data|rchild|parent
3
3.1遍历二叉树:
二叉树的遍历是指从根结点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问一次且仅被访问一次。
关键词:访问 次序
3.2二叉树遍历的方法:
3.2.1按从左到右:
1.前序遍历:
若二叉树为空,则空操作返回,
否则先访问根结点,然后前序遍历左子树,再前序遍历右子树。
算法:
void PreOrderTraverse(BiTree T)
{
if(T == NULL)
{
return;
}
printf("%c", T->data);
preOrder(T->lchild);
preOrder(T->rchild);
}
2.中序遍历:
若二叉树为空,则空操作返回,
否则从根结点开始(不是先访问根结点),中序遍历根结点的左子树,然后访问根结点,最后中序遍历右子树。
算法:
void InOrderTraverse(BiTree T)
{
if(T == NULL)
{
return;
}
InOrderTraverse(T->lchild);
printf("%c",T->data);
InOrderTraverse(T->rchild);
}
3.后序遍历:
若二叉树为空,则空操作返回,
否则从左到右先叶子后结点的方式遍历访问左右子树,最后是访问根结点。
算法:
void PosOrderTraverse(BiTree T)
{
if(T == NULL)
{
return;
}
PosOrderTraverse(T->lchild);
PosOrderTraverse(T->rchild);
printf("%c", T->data);
}
4.层序遍历:
若二叉树为空,则空操作返回,
否则从树的第一层,也就是根结点开始访问,从上而下逐层遍历,再同一层中,从左向右的顺序对结点逐个访问。
二叉树性质:
1.已知前序遍历序列和中序遍历序列,可以唯一确定一棵二叉树;
2.已知后序遍历序列和中序遍历序列,可以唯一确定一棵二叉树;
3.已知前序遍历和后序遍历,是不能确定一颗二叉树的
3.1遍历二叉树:
二叉树的遍历是指从根结点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问一次且仅被访问一次。
关键词:访问 次序
3.2二叉树遍历的方法:
3.2.1按从左到右:
1.前序遍历:
若二叉树为空,则空操作返回,
否则先访问根结点,然后前序遍历左子树,再前序遍历右子树。
算法:
void PreOrderTraverse(BiTree T)
{
if(T == NULL)
{
return;
}
printf("%c", T->data);
preOrder(T->lchild);
preOrder(T->rchild);
}
2.中序遍历:
若二叉树为空,则空操作返回,
否则从根结点开始(不是先访问根结点),中序遍历根结点的左子树,然后访问根结点,最后中序遍历右子树。
算法:
void InOrderTraverse(BiTree T)
{
if(T == NULL)
{
return;
}
InOrderTraverse(T->lchild);
printf("%c",T->data);
InOrderTraverse(T->rchild);
}
3.后序遍历:
若二叉树为空,则空操作返回,
否则从左到右先叶子后结点的方式遍历访问左右子树,最后是访问根结点。
算法:
void PosOrderTraverse(BiTree T)
{
if(T == NULL)
{
return;
}
PosOrderTraverse(T->lchild);
PosOrderTraverse(T->rchild);
printf("%c", T->data);
}
4.层序遍历:
若二叉树为空,则空操作返回,
否则从树的第一层,也就是根结点开始访问,从上而下逐层遍历,再同一层中,从左向右的顺序对结点逐个访问。
二叉树性质:
1.已知前序遍历序列和中序遍历序列,可以唯一确定一棵二叉树;
2.已知后序遍历序列和中序遍历序列,可以唯一确定一棵二叉树;
3.已知前序遍历和后序遍历,是不能确定一颗二叉树的
4.二叉树的建立
举例:前序遍历
void CreateBiTree(BiTree *T)
{
int ch;
scanf("%c", &ch);
if(ch == '#')
{
*T = NULL;
}
else
{
*T = (BiTree)malloc(sizeof(BiTNode));
if(!*T)
{
return ERROR;
}
(*T)->data = ch;
CreateBiTree(&(*T)->lchild);
CreateBiTree(&(*T)->rchild);
}
}