table of Contents
The basic operation of the tree
Preamble, in order, a subsequent traversal (recursive)
Preorder traversal (non-recursive, by means of the stack)
In order traversal (non-recursive, by means of the stack)
Postorder (non-recursive, by means of the stack)
Traverse the level (through queue)
Height function returns a binary tree height
Size function returns the number of nodes in a binary tree
The basic operation of the tree
Binary tree node structure definition
typedef struct btnode *btlink //定义一个指向数据类型为btnode的指针
typedef struct btnode
{
TreeItem element;
btlink *lchild;
btlink *rchild;
}Btnode;
Create a new tree node
btlink NewBNode() //返回值是一个指针,即新结点的地址值
{
btlink p;
p=malloc(sizeof(Btnode));
if(p) //申请地址成功
return p;
else
Error("Exhausted memory.");
}
Binary tree structure definition
typedef struct binarytree *BinaryTree;
typedef struct binarytree
{
btlink root; //root是指向树根的指针,一个二叉树只要知道其树根便可唯一确定
}BTree;
Creating an empty binary tree
BinaryTree BinaryInit()
{
BinaryTree T=malloc(sizeof(*T));
T->root=0; //初始化指针,未指向任何空间
return T;
}
Root BinaryEmpty (T) T is detected root pointer is empty
int BinaryEmpty(BinaryTree T) //这里的T是指针,指向一个二叉树的根结点
{
return(T->root==0)
}
Root (T) to return the root node numeral
TreeItem Root(BinaryTree T)
{
if(BinaryEmpty(T))
{
Error("Tree is empty.");
}
else return T->root->element;
}
MakeTree (x, T, L, R) to x is a root element, respectively, L and R for the left and right subtree construct a new binary tree T.
void MakeTree(TreeItem x,BinaryTree T,BinaryTree L,BinaryTree,R)
{
T->root=NewBNode();
T->root->data=x;
T->root->lchild=L->root;
T->root->rchild=R->root;
L->root=R->root=0;
}
Function BreakTree (T, L, R) execute a function MakeTree inverse operation of the binary tree split root element T element, 3 L three parts left subtree and right subtree R and the like.
TreeItem BreakTree(BinaryTree T,BinaryTree L,BinaryTree R)
{
TreeItem x;
if(!T->root) Error("Tree is Empty!");
x=T->root->element;
L->root=T->root->lchild;
R->root=T->root->rchild;
T->root=0;
return x;
}
Preamble, in order, a subsequent traversal (recursive)
void PreOrder(void (*visit)(btlink u),btlink t)
{
/*前序遍历*/
if(t)
{
(*visit)(t);
PreOrder(visit,t->lchild);
PreOrder(visit,t->rchild);
}
}
void InOrder(void (*visit)(btlink u),btlink t)
{
/*中序遍历*/
if(t)
{
PreOrder(visit,t->lchild);
(*visit)(t);
PreOrder(visit,t->rchild);
}
}
void PostOrder(void (*visit)(btlink u),btlink t)
{
/*后序遍历*/
if(t)
{
PreOrder(visit,t->lchild);
PreOrder(visit,t->rchild);
(*visit)(t);
}
}
Preorder traversal (non-recursive, by means of the stack)
//前序遍历
void PreOrderWithoutRecursion1(BTNode* root)
{
if (root == NULL)
return;
BTNode* p = root;
stack<BTNode*> s;
while (!s.empty() || p)
{
//边遍历边打印,并存入栈中,以后需要借助这些根节点(不要怀疑这种说法哦)进入右子树
while (p)
{
cout << setw(4) << p->data;
s.push(p);
p = p->lchild;
}
//当p为空时,说明根和左子树都遍历完了,该进入右子树了
if (!s.empty())
{
p = s.top();
s.pop();
p = p->rchild;
}
}
cout << endl;
}
void preorderNonrecursion(BTNode *bt)
{
if(bt!=NULL)
{
stack<BTNode*> s;
BTNode *p;
s.push(bt);
while(!IsEmpty(s))
{
p=s.pop(); //每有一个结点进栈,就执行一次弹出栈顶结点并压入其右左孩子结点的操作
visit(p);
if(p->rchild!=NULL) //记住是右子树先入栈,左子树后入栈,才能保证左子树先于右子树被访问
s.push(p->rchild);
if(p->lchild!=NULL)
s.push(p->lchild);
}
}
}
In order traversal (non-recursive, by means of the stack)
//中序遍历
/*若栈顶结点左孩子存在,则左孩子入栈,若左孩子不存在,则输出并弹出栈顶,然后检查其右孩子是否存在,若存在则右孩子入栈*/
void InOrderWithoutRecursion1(BTNode* root)
{
//空树
if (root == NULL)
return;
//树非空
BTNode* p = root;
stack<BTNode*> s;
while (!s.empty() || p)
{
//一直遍历到左子树最下边,边遍历边保存根节点到栈中
while (p)
{
s.push(p);
p = p->lchild;
}
//当p为空时,说明已经到达左子树最下边,这时需要出栈了
if (!s.empty())
{
p = s.top();
s.pop();
cout << setw(4) << p->data;
//进入右子树,开始新的一轮左子树遍历(这是递归的自我实现)
p = p->rchild; //如果有右子树,就走while,把右子树压入栈,若无右子树,就走if,继续弹出栈顶元素
}
}
}
Postorder (non-recursive, by means of the stack)
//后序遍历
//定义枚举类型:Tag
enum Tag{left,right};
//自定义新的类型,把二叉树节点和标记封装在一起
typedef struct
{
BTNode* node;
Tag tag;
}TagNode;
//后序遍历
void PostOrderWithoutRecursion2(BTNode* root)
{
if (root == NULL)
return;
stack<TagNode> s;
TagNode tagnode;
BTNode* p = root;
while (!s.empty() || p)
{
while (p)
{
tagnode.node = p;
//该节点的左子树被访问过
tagnode.tag = Tag::left;
s.push(tagnode);
p = p->lchild;
}
tagnode = s.top();
s.pop();
//左子树被访问过,则还需进入右子树
if (tagnode.tag == Tag::left)
{
//置换标记
tagnode.tag = Tag::right;
//再次入栈
s.push(tagnode);
p = tagnode.node;
//进入右子树
p = p->rchild;
}
else//右子树已被访问过,则可访问当前节点
{
cout << setw(4) << (tagnode.node)->data;
//置空,再次出栈(这一步是理解的难点),p=NULL下一层循环直接执行while(p){}后面的语句,即继续弹出栈顶
p = NULL;
}
}
cout << endl;
}
/*依据:逆后序遍历=先序遍历中左右子树访问顺序对调*/
void postordernonrecursion(BTNode *bt)
{
stack <BTNode*> s1,s2;
BTNode *p;
s1.push(bt);
while(!IsEmpty(s1))
{
p=s1.pop();
s2.push(p); //访问到的结点压入s2
if(p->lchild!=NULL)
s1.push(p->lchild);
if(p->rchild!=NULL)
s2.push(p->rchild); //先压入左子树再压入右子树,保证弹栈时先弹出右子树
}
while(!IsEmpty(s2))
{
p=s2.pop();
visit(p);
}
}
Traverse the level (through queue)
void LevelOrder(void (*visit)(btlink u),btlink t)
{
Queue q=QueueInit();
EnQueue(t,q);
while(!QueueEmpty(q))
{
(*visit)(t=DeQueue(q));
if(t->lchild) EnQueue(t->lchild,q);
if(t->rchild) EnQueue(t->rchild,q);
}
}
void Level(BTNode *bt)
{
InitQueue(Q);
BTNode *p;
EnQueue(Q,bt);
while(!IsEmpty(Q))
{
DeQueue(Q,p);
visit(p);
if(p->lchild!=NULL)
EnQueue(Q,p->lchild);
if(p->rchild!=NULL)
EnQueue(Q,p->rchild);
}
}
Height function returns a binary tree height
int Height(btlink t)
{
int hl,hr;
if(!t) return -1;
hl=Height(t->lchild);
hr=Height(t->rchild);
return hl>hr?++hl:++hr;//取左右子树中高度较大者的高度加上自身根结点的高度
}
Size function returns the number of nodes in a binary tree
int Size(btlink t)
{
if(!t) return 0;
int lsize=Size(t->lchild);
int rsize=Size(t->rchild);
return lsize+rsize+1;//左子树结点数+右子树结点数+自身根结点数1
}