一、前序遍历
void PreOrderRec(Btree* root)
{
if (root == NULL)
{
return;
}
printf("- %d -", root->data);
PreOrderRec(root->lchild);
PreOrderRec(root->rchild);
}
二、(借助栈)前序遍历
void PreOrder(Btree* root)
{
Bnode cur;
if (root == NULL)
{
return;
}
SqStack stack;
InitStack(stack);
PushStack(stack, *root); //头节点先入栈
while (!(IsEmpty(stack))) //栈为空,所有节点均已处理
{
PopStack(stack, cur); //要遍历的节点
printf("- %d -", cur.data);
if (cur.rchild != NULL)
{
PushStack(stack, *(cur.rchild)); //右子节点先入栈,后处理
}
if (cur.lchild != NULL)
{
PushStack(stack, *(cur.lchild)); //左子节点后入栈,接下来先处理
}
}
DestroyStack(stack);
}
三、中序遍历
先访问根节点的左子树,然后访问根节点,最后遍历根节点的右子树
void PreOrderRec2(Btree *root)
{
if(root == NULL)
return ;
PreOrderRec2(root->lchild);
printf("-%d-",root->data);
PreOrderRec2(root->rchild);
}
四、(借助栈)中序遍历
void PreOrder2(Btree* root)
{
Bnode* cur = root;
Bnode cur1;
if(root == NULL)
return ;
SqStack stack;
InitStack(stack);
while(!(IsEmpty(stack))|| cur!=NULL)
{
while(cur!=NULL)
{
PushStack(stack,*cur);
cur = cur->lchild;
}
PopStack(stack,cur1);//出栈 (根节点,记录器)
printf("-%d-",cur1.data);//打印出栈元素
if(cur1.rchild!=NULL)
cur = cur1.rchild;
}
DestroyStack(stack);
}
五、后序遍历
从左到右,先叶子后结点的方式遍历访问左右子树,最后访问根节点
void PreOrderRec3(Btree *root)
{
if(root == NULL)
return ;
PreOrderRec3(root->lchild);
PreOrderRec3(root->rchild);
printf("-%d-",root->data);
}
删除结点
Btree* DeleteNode(Btree* root,int key, Bnode* &deletedNode)
{
if(root==NULL)//没有找到删除节点
return NULL;
if(root->data>key)//根节点的数据大于 要删除的节点,就往左子树上面找
{
root->lchild = DeleteNode(root->lchild,key, deletedNode);//左子树的节点递归成新的根节点
return root;
}
if(root->data<key)//根节点的数据小于 要删除的节点,就往右子树上面找
{
root->rchild = DeleteNode(root->rchild,key, deletedNode);//右子树的节点递归成新的根节点
return root;
}
deletedNode = root;//告诉main函数,被删除的是哪一个数据
//走到这里说明已经找到了要删除的节点,此时的root就是目标节点
//删除节点不存在左右子节点,即为叶子节点,直接删除
if(root->lchild==NULL&&root->rchild==NULL)
return NULL;
//删除节点只存在左子节点,直接用那个左子节点替代要删除的节点
if(root->lchild!=NULL&&root->rchild==NULL)
return root->lchild;
//删除节点只存在右子节点,直接用那个右子节点替代要删除的节点
if(root->rchild!=NULL&&root->lchild==NULL)
return root->rchild;
//删除节点存在左右节点,直接用要删除节点的左子节点最大值或右子节点的最小值替代删除节点
int val = findMax(root->lchild); // int val = findMax(root->rchild);
root->data = val;//用左子树上的最大节点 取代删除节点
root->lchild = DeleteNode(root->lchild,val, deletedNode);//递归把左子树的最大节点置空, 上面if(root->data<key)返回的root就是左子树的根节点
return root;
}
查找
/*非递归法查找*/
Bnode* queryByLoop(Btree* root,ElemType e)
{
while(root!=NULL && !isEqual(root->data,e))
{
if(isLess(e,root->data))
root = root->lchild;
else
root = root->rchild;
}
return root;
}
/*递归法查找*/
Bnode* queryByRec(Btree* root,ElemType e)
{
if(root == NULL ||isEqual(root->data,e))//找不到该节点 || 找到了该节点 找到了直接返回目标节点到第一次调用该函数的地方
return root;
else if(isLess(e,root->data))
return queryByRec(root->lchild,e);
else
return queryByRec(root->rchild,e);
}
找出最大结点
int findMax(Btree* root)
{
if(!root)
{
cout<<"finMax()函数报错!";
return false;
}
/*方式一:递归
if(root->rchild == NULL)
{
return root->data;
}
return findMax(root->rchild);
*/
/*方式二:循环*/
while(root->rchild)
{
root = root->rchild;
}
return root->data;
}