数据结构实例精讲二叉树的遍历和应用.docx
- 文档编号:30667341
- 上传时间:2023-08-19
- 格式:DOCX
- 页数:73
- 大小:74.05KB
数据结构实例精讲二叉树的遍历和应用.docx
《数据结构实例精讲二叉树的遍历和应用.docx》由会员分享,可在线阅读,更多相关《数据结构实例精讲二叉树的遍历和应用.docx(73页珍藏版)》请在冰豆网上搜索。
数据结构实例精讲二叉树的遍历和应用
数据结构实例精讲:
二叉树的遍历和应用
5.3二叉树的遍历
遍历是二叉树的一种重要运算。
二叉树的遍历是指按一定的次序访问二叉树中的每个结点,使每个结点被访问一次且只被访问一次。
根据二叉树的定义知道,一棵二叉树可看作由三部分组成:
根结点、左子树和右子树,若规定D、L、R分别表示“访问根结点”、“遍历根结点的左子树”和“遍历根结点的右子树”,则二叉树的遍历共有六种方式:
DLR、LDR、LRD、DRL、RDL、RLD。
若又规定按先左子树后右子树的顺序进行遍历,则遍历有三种方式:
DLR、LDR和LRD,它们分别被称为先序遍历、中序遍历和后序遍历。
另外,还有一种按二叉树中结点由上至下、由左到右的顺序进行遍历的方式,称为层次遍历。
对于图5-8所示的二叉树,按先序遍历方式进行遍历所得到的结果序列为ABDGCEHIF,按中序遍历方式进行遍历所得到的结果序列为DGBAHEICF,按后序遍历方式进行遍历所得到的结果序列为GDBHIEFCA,按层次遍历方式进行遍历所得到的结果序列为ABCDEFGHI。
【实例5-6】先序遍历。
编写一个程序,输出指定二叉树的先序遍历序列。
(1)问题分析。
先序遍历的方法为:
若二叉树为空,遍历结束,否则,①访问根结点;②先序遍历根结点的左子树;③先序遍历根结点的右子树。
由于先序遍历的方法采用的是递归定义,因此,很容易写出其递归算法。
voidBinTree_DLR(BiTreebt)
{
if(bt){
cout<
BinTree_DLR(bt->lchild);//先序遍历根结点的左子树
BinTree_DLR(bt->rchild);//先序遍历根结点的右子树
}
}
下面主要讨论先序遍历的非递归实现方法。
对于非递归算法,引入栈模拟递归工作栈,初始时栈为空。
在遍历二叉树T的过程中,用栈来保存信息,使得在先序遍历完左子树后,能利用栈顶信息获取二叉树T的右子树的根指针。
具体做法是:
访问T->data后,将T->rchild入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T->rchild,出栈,遍历以该指针为根的子树。
(2)函数程序代码。
voidBinTree_PreOrder(BiTreebt)
{
inttop=0;//top是栈s的栈顶指针
BiTNode*s[20];
while(bt!
=NULL||top>0)
{
while(bt!
=NULL)
{
cout<
if(bt->rchild)s[++top]=bt->rchild;
bt=bt->lchild;
}
if(top>0)bt=s[top--];
}
cout< } (3)函数应用的示例源程序。 #include usingnamespacestd; typedefcharTElemType; structBiTNode { TElemTypedata; BiTNode*lchild; BiTNode*rchild; }; typedefBiTNode*BiTree; voidPrintTreeNode(BiTNode*pNode) { if(pNode! =NULL) { cout<<"结点"< if(pNode->lchild! =NULL) cout<<"左子为"< else cout<<"左子为空"; if(pNode->rchild! =NULL) cout<<",右子为"< "< else cout<<",右子为空。 "< } } voidPrintTree(BiTreebt) { PrintTreeNode(bt); if(bt! =NULL) { if(bt->lchild! =NULL) PrintTree(bt->lchild); if(bt->rchild! =NULL) PrintTree(bt->rchild); } } voidDestroyTree(BiTree&bt) { if(bt! =NULL) { BiTNode*pLeft=bt->lchild; BiTNode*pRight=bt->rchild; deletebt; bt=NULL; DestroyTree(pLeft); DestroyTree(pRight); } } BiTNode*CreateBiTNode(charvalue) { BiTNode*pNode=newBiTNode(); pNode->data=value; pNode->lchild=NULL; pNode->rchild=NULL; returnpNode; } voidConnectTreeNodes(BiTNode*pParent,BiTNode*pLeft,BiTNode*pRight) { if(pParent! =NULL) { pParent->lchild=pLeft; pParent->rchild=pRight; } } voidCreateTestBinTree(BiTree&bt) { BiTNode*pNode1=CreateBiTNode('A'); BiTNode*pNode2=CreateBiTNode('B'); BiTNode*pNode3=CreateBiTNode('C'); BiTNode*pNode4=CreateBiTNode('D'); BiTNode*pNode5=CreateBiTNode('E'); BiTNode*pNode6=CreateBiTNode('F'); BiTNode*pNode7=CreateBiTNode('G'); BiTNode*pNode8=CreateBiTNode('H'); BiTNode*pNode9=CreateBiTNode('I'); ConnectTreeNodes(pNode1,pNode2,pNode3); ConnectTreeNodes(pNode2,pNode4,NULL); ConnectTreeNodes(pNode4,NULL,pNode7); ConnectTreeNodes(pNode3,pNode5,pNode6); ConnectTreeNodes(pNode5,pNode8,pNode9); bt=pNode1; } voidBinTree_DLR(BiTreebt) { if(bt) { cout< BinTree_DLR(bt->lchild); BinTree_DLR(bt->rchild); } } voidBinTree_PreOrder(BiTreebt) { inttop=0;//top是栈s的栈顶指针 BiTNode*s[20]; while(bt! =NULL||top>0) { while(bt! =NULL) { cout< if(bt->rchild)s[++top]=bt->rchild; bt=bt->lchild; } if(top>0)bt=s[top--]; } cout< } intmain() { BiTreebt; CreateTestBinTree(bt); cout<<"按先序遍历(递归算法)的结果为: "< BinTree_DLR(bt); cout< cout<<"按先序遍历(非递归算法)的结果为: "< BinTree_PreOrder(bt); DestroyTree(bt); return0; } 【实例5-7】中序遍历。 编写一个程序,输出指定二叉树的中序遍历序列。 (1)问题分析。 中序遍历的方法为: 若二叉树为空,遍历结束,否则,①中序遍历根结点的左子树;②访问根结点;③中序遍历根结点的右子树。 由于中序遍历的方法也采用的是递归定义,因此,很容易写出其递归算法。 voidBinTree_LDR(BiTreebt) { if(bt) { BinTree_LDR(bt->lchild); cout< BinTree_LDR(bt->rchild); } } 下面讨论中序遍历的非递归实现方法。 同样,引入栈模拟递归工作栈,初始时栈为空。 设T是要遍历树的根指针,中序遍历要求在遍历完左子树后,访问根,再遍历右子树。 具体方法是: 先将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,访问T->data,再中序遍历T的右子树。 (2)函数程序代码。 voidBinTree_InOrder(BiTreebt) { stack BiTNode*pNode; pNode=bt; while(pNode! =NULL||! s.empty()) { if(pNode! =NULL) { s.push(pNode);//pNode入栈 pNode=pNode->lchild; } else { pNode=s.top();s.pop();//栈顶元素出栈 cout< pNode=pNode->rchild; } } cout< } (3)函数应用的示例源程序。 #include #include usingnamespacestd; typedefcharTElemType; structBiTNode { TElemTypedata; BiTNode*lchild; BiTNode*rchild; }; typedefBiTNode*BiTree; voidPrintTreeNode(BiTNode*pNode) { if(pNode! =NULL) { cout<<"结点"< if(pNode->lchild! =NULL) cout<<"左子为"< else cout<<"左子为空"; if(pNode->rchild! =NULL) cout<<",右子为"< "< else cout<<",右子为空。 "< } } voidPrintTree(BiTreebt) { PrintTreeNode(bt); if(bt! =NULL) { if(bt->lchild! =NULL) PrintTree(bt->lchild); if(bt->rchild! =NULL) PrintTree(bt->rchild); } } voidDestroyTree(BiTree&bt) { if(bt! =NULL) { BiTNode*pLeft=bt->lchild; BiTNode*pRight=bt->rchild; deletebt; bt=NULL; DestroyTree(pLeft); DestroyTree(pRight); } } BiTNode*CreateBiTNode(charvalue) { BiTNode*pNode=newBiTNode(); pNode->data=value; pNode->lchild=NULL; pNode->rchild=NULL; returnpNode; } voidConnectTreeNodes(BiTNode*pParent,BiTNode*pLeft,BiTNode*pRight) { if(pParent! =NULL) { pParent->lchild=pLeft; pParent->rchild=pRight; } } voidCreateTestBinTree(BiTree&bt) { BiTNode*pNode1=CreateBiTNode('A'); BiTNode*pNode2=CreateBiTNode('B'); BiTNode*pNode3=CreateBiTNode('C'); BiTNode*pNode4=CreateBiTNode('D'); BiTNode*pNode5=CreateBiTNode('E'); BiTNode*pNode6=CreateBiTNode('F'); BiTNode*pNode7=CreateBiTNode('G'); BiTNode*pNode8=CreateBiTNode('H'); BiTNode*pNode9=CreateBiTNode('I'); ConnectTreeNodes(pNode1,pNode2,pNode3); ConnectTreeNodes(pNode2,pNode4,NULL); ConnectTreeNodes(pNode4,NULL,pNode7); ConnectTreeNodes(pNode3,pNode5,pNode6); ConnectTreeNodes(pNode5,pNode8,pNode9); bt=pNode1; } voidBinTree_LDR(BiTreebt) { if(bt) { BinTree_LDR(bt->lchild); cout< BinTree_LDR(bt->rchild); } } voidBinTree_InOrder(BiTreebt) { stack BiTNode*pNode; pNode=bt; while(pNode! =NULL||! s.empty()) { if(pNode! =NULL) { s.push(pNode);//pNode入栈 pNode=pNode->lchild; } else { pNode=s.top();s.pop();//栈顶元素出栈 cout< pNode=pNode->rchild; } } cout< } intmain() { BiTreebt; CreateTestBinTree(bt); cout<<"按中序遍历(递归算法)的结果为: "< BinTree_LDR(bt); cout< cout<<"按中序遍历(非递归算法)的结果为: "< BinTree_InOrder(bt); DestroyTree(bt); return0; } 【实例5-8】后序遍历。 编写一个程序,输出指定二叉树的后序遍历序列。 (1)问题分析。 后序遍历的方法为: 若二叉树为空,遍历结束,否则,①后序遍历根结点的左子树;②后序遍历根结点的右子树;③访问根结点。 由于后序遍历的方法也采用的是递归定义,因此,很容易写出其递归算法。 voidBinTree_LRD(BiTreebt) { if(bt) { BinTree_LRD(bt->lchild); BinTree_LRD(bt->rchild); cout< } } 下面主要讨论后序遍历的非递归实现方法。 设T是要后序遍历的二叉树的根指针,后序遍历要求在遍历完左右子树后,再访问根。 需要判断根结点的左右子树是否均遍历过。 可采用标记法,结点入栈时,配一个标志tag一同入栈(“L”: 遍历左子树前的现场保护,“R”: 遍历右子树前的现场保护)。 首先将T和tag(为L)入栈,遍历左子树;返回后,修改栈顶tag为R,遍历右子树;最后访问根结点。 (2)函数程序代码。 structstackNode{ BiTNode*ptr; chartag; }; voidBinTree_PostOrder(BiTreebt) { stack stackNodex; BiTNode*p; p=bt; do { while(p! =NULL)//遍历左子树 { x.ptr=p; x.tag='L';//标记为左子树 s.push(x); p=p->lchild; } while(! s.empty()&&s.top().tag=='R') { x=s.top();s.pop(); p=x.ptr; cout< } if(! s.empty()) { s.top().tag='R';//遍历右子树 p=s.top().ptr->rchild; } }while(! s.empty()); cout< } (3)函数应用的示例源程序。 #include #include usingnamespacestd; typedefcharTElemType; structBiTNode { TElemTypedata; BiTNode*lchild; BiTNode*rchild; }; typedefBiTNode*BiTree; voidPrintTreeNode(BiTNode*pNode) { if(pNode! =NULL) { cout<<"结点"< if(pNode->lchild! =NULL) cout<<"左子为"< else cout<<"左子为空"; if(pNode->rchild! =NULL) cout<<",右子为"< "< else cout<<",右子为空。 "< } } voidPrintTree(BiTreebt) { PrintTreeNode(bt); if(bt! =NULL) { if(bt->lchild! =NULL) PrintTree(bt->lchild); if(bt->rchild! =NULL) PrintTree(bt->rchild); } } voidDestroyTree(BiTree&bt) { if(bt! =NULL) { BiTNode*pLeft=bt->lchild; BiTNode*pRight=bt->rchild; deletebt; bt=NULL; DestroyTree(pLeft); DestroyTree(pRight); } } BiTNode*CreateBiTNode(charvalue) { BiTNode*pNode=newBiTNode(); pNode->data=value; pNode->lchild=NULL; pNode->rchild=NULL; returnpNode; } voidConnectTreeNodes(BiTNode*pParent,BiTNode*pLeft,BiTNode*pRight) { if(pParent! =NULL) { pParent->lchild=pLeft; pParent->rchild=pRight; } } voidCreateTestBinTree(BiTree&bt) { BiTNode*pNode1=CreateBiTNode('A'); BiTNode*pNode2=CreateBiTNode('B'); BiTNode*pNode3=CreateBiTNode('C'); BiTNode*pNode4=CreateBiTNode('D'); BiTNode*pNode5=CreateBiTNode('E'); BiTNode*pNode6=CreateBiTNode('F'); BiTNode*pNode7=CreateBiTNode('G'); BiTNode*pNode8=CreateBiTNode('H'); BiTNode*pNode9=CreateBiTNode('I'); ConnectTreeNodes(pNode1,pNode2,pNode3); ConnectTreeNodes(pNode2,pNode4,NULL); ConnectTreeNodes(pNode4,NULL,pNode7); ConnectTreeNodes(pNode3,pNode5,pNode6); ConnectTreeNodes(pNode5,pNode8,pNode9); bt=pNode1; } structstackNode{ BiTNode*ptr; chartag; }; voidBinT
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 实例 二叉 遍历 应用