数据结构之二叉树的常见操作Word下载.docx
《数据结构之二叉树的常见操作Word下载.docx》由会员分享,可在线阅读,更多相关《数据结构之二叉树的常见操作Word下载.docx(12页珍藏版)》请在冰豆网上搜索。
![数据结构之二叉树的常见操作Word下载.docx](https://file1.bdocx.com/fileroot1/2022-11/25/65e8c564-922d-4bb6-8295-afed12bb9ecf/65e8c564-922d-4bb6-8295-afed12bb9ecf1.gif)
<
"
noRecursionInorderTraversal--------------------------->
"
endl;
linkedStackType<
nodeType<
*>
stack;
nodeType<
*current=root;
while(current!
=NULL||!
stack.isEmptyStack())//或者||
if(current!
=NULL)
stack.push(current);
current=current->
llink;
}
else
stack.pop(current);
current->
info<
\t"
;
//出栈的时候访问节点
rlink;
------------------------noRecursionInorderTraversal"
2.
非递归先序遍历
//在中序遍历的基础上,访问次序发生变化;
//先序遍历,需要先逐个遍历根节点,然后依次处理其左、右孩子节点。
noRecursionPreorderTraversal()//非递归前序遍历
noRecursionPreorderTraversal--------------------------->
//先访问节点后入栈
------------------------noRecursionPreorderTraversal"
3.
非递归后序遍历
由于访问的顺序为先左子树、然后右子树,最后根节点。
并且对于每一个节点都是上述操作,所以,对于遍历来讲,需要识别当前节点类型是根(相对)、左孩子节点、右孩子节点。
故,我们设定了flag标记变量,flag=0初始标记,节点尚未入栈;
在访问左孩子之前将flag置为1;
在访问右孩子之前将flag置为2;
并且在访问右孩子之后,将flag置为0。
//后序非递归遍历比较复杂..
voidbinaryTreeType<
noRecursionPostorderTraversal()//非递归后序遍历
noRecursionPostorderTraversal--------------------------->
int>
intStack;
//标记位同步栈.
intnflag=0;
//初始标记为0.
if(current==NULL)
TheStackisEmpty!
<
//1.将头节点先入栈,
intStack.push
(1);
current=current->
//注意此处需要调整指向******
while(!
stack.isEmptyStack()&
&
!
intStack.isEmptyStack())
=NULL&
nflag==0)
//标记位为1,[在访问左孩子之前,将其值置为1]。
intStack.pop(nflag);
//此时的标记位为返回值,需要根据其做判断
if(nflag==1)//说明下一步需要入栈的为右孩子.
//继续将该节点入栈,
intStack.push
(2);
//但[在访问右孩子之前,将其置为2]。
//访问右节点,
nflag=0;
//置标记位为0
//待左右子树都为空再访问节点。
------------------------noRecursionPostorderTraversal"
}
4.
二叉排序树的搜索操作
明确概念,国内、国外的著作里提及的下三个概念等价,二叉搜索树=二叉查找树=二叉排序树。
//二叉排序树的查找存在以下几种情况:
//1.链表为空,提示并返回;
//2.链表非空,需要循环查找直到指针为空,若存在,则bfound=true;
否则查找至最后bfound=缺省false。
template<
classelemType>
boolbSearchTreeType<
search(constelemType&
searchItem)
{
*current=newnodeType<
boolbFound=false;
if(root==NULL)
ThebSearchTreeisNULL\n"
//case1:
链表为空!
returnfalse;
current=root;
bFound)//case2:
在链表中查找,根据大小锁定左、右子树.
if(current->
info==searchItem)
bFound=true;
elseif(current->
info>
//左子树
//右子树
returnbFound;
}
5.
二叉排序树的插入存在以下几种情况:
//1.链表为空,插入元素即为根节点;
//2.链表非空,需要寻找插入位置后插入。
//2.1插入元素已经存在,则提示出错。
//2.2总能找到大于或小于某节点的位置,记录trailcurrent完成插入操作。
voidbSearchTreeType<
insert(constelemType&
insertItem)
*newNode=newnodeType<
*current;
*trailCurrent;
newNode->
info=insertItem;
llink=NULL;
rlink=NULL;
root=newNode;
树为空.
=NULL)//case2,3,4搜索才知道!
trailCurrent=current;
info==insertItem)
theelemisalreadyexist!
\n"
//case2:
元素已经存在
return;
info>
//case3:
锁定左侧位置...
//case4:
锁定右侧位置...
}//endwhile
//case3,4根据大小进行链接
if(trailCurrent->
info<
insertItem)
trailCurrent->
rlink=newNode;
llink=newNode;
}//endelse
6.
二叉排序树的删除存在以下几种情况【此处可能复杂些】:
//删除一个节点,要首先判断元素值在二叉排序树中是否存在,
//若不存在则返回;
//若存在则需要锁定其对应位置为1根节点;
2叶节点;
3其余节点。
//根据要删除的节点是否含有左右子树的不同,分为4种情况考虑,
//见deleteFromTree()函数。
deleteNode(constelemType&
deleteItem)
//1.查找节点
//2.1找不到,不存在;
//2.2找到,删除,调用函数
Can'
tdeleteanEmptyBST"
trailCurrent=root;
while(current!
bFound)
info==deleteItem)
//左
//右
deleteItem<
isnotExistintheBST!
endl;
elseif(bFound)
if(current==root)
deleteFromTree(root);
//可能是根节点
elseif(trailCurrent->
deleteFromTree(trailCurrent->
llink);
//左半分支,调整trailCurrent的指向
rlink);
//右半分支,调整trailCurrent的指向
}//endifbFound
//[原理]:
某节点的前驱是该节点左子树的最右端的节点(中序遍历的结果)
deleteFromTree(nodeType<
*&
p)
*temp;
if(p==NULL)
TheBSTisNULL!
if(p->
llink==NULL&
p->
rlink==NULL)//情况1,左右节点都为空(叶节点)
temp=p;
p=NULL;
deletetemp;
elseif(p->
rlink==NULL)//情况2,右子树为空,左非空
p=temp->
elseif(p->
llink==NULL)//情况3,左子树为空,右非空
else//情况4,左右都非空[用中序遍历的前一个节点替换]
current=p->
trailCurrent=NULL;
while(current->
rlink!
//trailCurrent最终指向准备删除节点的前一个节点
info=current->
info;
//信息赋值
if(trailCurrent==NULL)//仅一个左孩子节点
rlink=current->
rlink=current->
//给删除前点的前面一个节点调整指针指向
deletecurrent;