文章目录
思路
先序遍历:若二叉树为空,则空操作;否则访问根节点;先序遍历左子树;先序遍历右子树。
中序遍历:若二叉树为空,则空操作;否则中序遍历左子树;访问根节点;中序遍历右子树。
后序遍历:若二叉树为空,则空操作;否则后序遍历左子树;后序遍历右子树;访问根节点。
二叉链表:链表中的结点包含三个域:数据域和左右指针域。
方法实现
1.二叉树的二叉链表存储表示
typedef char TElemType;
typedef struct BiNode
{
TElemType data;
struct BiNode *lchild, *rchild;
} BiNode , *BiTree;
2.生成二叉树
先序建立二叉树的二叉链表
/*
* 按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树,构造二叉链表表示的二叉树T。
*/
Status CreatBiTree(BiTree *T)
{
char ch;
scanf("%c", &ch);
//如果当前输入的字符为空格,则(*T)指向空树。
if (ch == ' ')
{
(*T) = NULL;
}
else
{
if (!((*T) = (BiTree)malloc(sizeof(BiNode))))
exit(OVERFLOW);
(*T)->data = ch; //生成根结点
CreatBiTree(&((*T)->lchild)); //构造左子树
CreatBiTree(&((*T)->rchild)); //构造右子树
}
return OK;
}
3.二叉树遍历递归算法
(1)先序遍历
/*
* 采用二叉链表存储结构,Visit是对数据元素操作的应用函数,
* 先序遍历二叉树T的递归算法,对每个数据元素调用函数Visit。
*/
Status PreOrderTraverse_Recursive(BiTree T, Status(*Visit)(TElemType e))
{
if (T)
{
if (Visit(T->data))
if (PreOrderTraverse_Recursive(T->lchild, Visit))
if (PreOrderTraverse_Recursive(T->rchild, Visit))
return OK;
return ERROR; //函数不会执行到这一步,不会返回Error。这样写只是为了没有编译警告。
}
else
return OK; //当T为空树时,停止递归。
}
(2)中序遍历
Status InOrderTraverse_Recursive(BiTree T, Status(*Visit)(TElemType e))
{
if (T)
{
if (InOrderTraverse_Recursive(T->lchild, Visit))
if (Visit(T->data))
if (InOrderTraverse_Recursive(T->rchild, Visit))
return OK;
return ERROR;
}
else
return OK;
}
(3)后序遍历
Status PostOrderTraverse_Recursive(BiTree T, Status(*Visit)(TElemType e))
{
if (T)
{
if (PostOrderTraverse_Recursive(T->lchild, Visit))
if (PostOrderTraverse_Recursive(T->rchild, Visit))
if (Visit(T->data))
return OK;
return ERROR;
}
else
return OK;
}
4.二叉树遍历非递归算法
(1)先序遍历
/*
* 先序遍历二叉树,非递归算法。
*/
Status PreOrderTraverse_NonRecursive(BiTree T, Status(*Visit)(TElemType e))
{
Stack *S; //栈S中存储指向树结点的指针。
BiTree p;
S = (Stack*)malloc(sizeof(Stack));
InitStack(S);
Push(S, T); //根指针进栈。
while (!StackEmpty(S))
{
//获取栈顶指针,如果栈顶指针不为空,访问该结点。并将该结点的左子树进栈。
if (GetTop(S, &p) && p)
{
if (!Visit(p->data))
return ERROR;
Push(S, p->lchild);
}
//栈顶指针为空,表明之前压入的左子树或者右子树为空。
else
{
Pop(S, &p); //空指针退栈
if (!StackEmpty(S))
{
Pop(S