目录
树的性质
二叉树五种形态
二叉树的层次建树 (必须掌握)
二叉树结构体定义
//二叉树结构体定义
typedef struct BiTNode {
BiElemType c; //数据域
struct BiTNode* lchild; //左孩子指针
struct BiTNode* rchild; //右孩子指针
}BiTNode, * BiTree;
辅助建树的队列的结构体
typedef struct tag
{
BiTree p; //树的某一个结点的地址值
struct tag* pnext;
}tag_t, * ptag_t;
建树的主要代码
BiTree pnew;
int i, j, pos;
char c;
BiTree tree = NULL; //树根置空
ptag_t phead = NULL, ptail = NULL, listpnew = NULL, pcur = NULL;//phead就是队列头,ptail就是队列尾
//abcdefghij
while (scanf("%c", &c) != EOF)
{
if (c == '\n')
{
break;
}
pnew = (BiTree)calloc(1, sizeof(BiTNode)); //calloc申请空间并对空间进行初始化,赋值为0
pnew->c = c;//数据放进去
listpnew = (ptag_t)calloc(1, sizeof(tag_t));//给队列结点申请空间
listpnew->p = pnew;
if (tree == NULL)
{
tree = pnew;//树的根
phead = listpnew;//队列头
ptail = listpnew;//队列尾
pcur = listpnew;
continue;
}
else
{
ptail->pnext = listpnew;//新结点放入链表,通过尾插法
ptail = listpnew;//ptail指向队列尾部
}//pcur始终指向要插入的结点的位置
if (pcur->p->lchild == NULL)//如何把新结点放入树,也就是判断根节点的左边为空
{
pcur->p->lchild = pnew;//把新结点放到要插入结点的左边
}
else if (pcur->p->rchild == NULL)
{
pcur->p->rchild = pnew; //把新结点放到要插入结点的右边
pcur = pcur->pnext; //左右都放了结点后,pcur指向队列的下一个
}
}
二叉树的遍历(必须掌握)
采用递归实现
遍历的示意图
前序遍历
//前序遍历,前序遍历就是深度优先遍历
void preOrder(BiTree p)
{
if (p != NULL)
{
putchar(p->c);//等价于visit函数 ,打印根节点
preOrder(p->lchild); //打印左子树
preOrder(p->rchild); //打印右子树
}
}
中序遍历
//中序遍历
void InOrder(BiTree p)
{
if (p != NULL)
{
InOrder(p->lchild);//打印左子树
putchar(p->c); //打印根节点
InOrder(p->rchild); //打印右子树
}
}
后序遍历
// 后序遍历
void PostOrder(BiTree p)
{
if (p != NULL)
{
PostOrder(p->lchild); //打印左子树
PostOrder(p->rchild);//打印右子树
putchar(p->c); //打印根结点
}
}
非递归实现中序遍历
//中序遍历非递归,非递归执行效率更高
void InOrder2(BiTree T)
{
SqStack S;
InitStack(S);
BiTree p = T;
while (p || !StackEmpty(S))//逻辑或||
{
if (p)
{//当一个结点不为空,压栈,并取左孩子
Push(S, p);
p = p->lchild;
}
else {//弹出栈中元素并打印,获取打印元素的右结点
Pop(S, p); putchar(p->c);
p = p->rchild;
}
}
}
层次遍历
//层次遍历,层序遍历,广度优先遍历
void LevelOrder(BiTree T)
{
LinkQueue Q;//辅助队列
InitQueue(Q);//初始化队列
BiTree p;
EnQueue(Q, T);//树根入队
while (!IsEmpty(Q))
{
DeQueue(Q, p);//出队当前结点并打印
putchar(p->c);
if (p->lchild != NULL) //入队左孩子