赞
踩
先序遍历、中序遍历、后序遍历、层次遍历(广度优先遍历)
先序、中序和后序遍历过程: 遍历过程中经过的结点的路线一样,只是访问各结点的时机不一样,都是深度优先遍历
从入口到出口的曲线上用圆圈叉号、星号和三角三种符号分别标记出了先序、中序和后序访问各结点的时刻
层次遍历: 广度优先遍历
递归实现、非递归实现
//data.txt
9
A 1 2
B 3 4
C 5 6
D - -
F 7 -
G - 8
I - -
E - -
H - -
typedef struct BiNode
{
char data;
BiNode *lChild=NULL;
BiNode *rChild=NULL;
} BiNode,*BiTree;
BiTree createTree(string filename) { std::ifstream fin; fin.open(filename.c_str()); int nodesize; fin>>nodesize; BiTree nodelist=new BiNode[nodesize]; for(int i=0;i<nodesize;i++) { char data, lc,rc; fin>>data>>lc>>rc; nodelist[i].data=data; if(lc!='-') { nodelist[i].lChild=nodelist+(lc-'0');//指向数组相应的位置 } else { nodelist[i].lChild=NULL; } if(rc!='-') { nodelist[i].rChild=nodelist+(rc-'0'); } else { nodelist[i].rChild=NULL; } } fin.close(); return nodelist; }
Preoreder traversal:
A B D F E C G H I
//递归前序遍历
void RecursionPreOrderTraversal(BiTree bitree)
{
if(bitree)
{
std::cout<<bitree->data<<" ";
RecursionPreOrderTraversal(bitree->lChild);
RecursionPreOrderTraversal(bitree->rChild);
}
}
主要思路:使用堆栈。堆栈的作用是保存父节点,遍历完左子树后,弹出栈顶并遍历其右子树
//非递归前序遍历 void NonRecursionPreOrderTraversal(BiTree bitree) { std::stack<BiNode*> mystack; BiNode* BN=bitree;//用于遍历的指针 while(BN||!mystack.empty()) { while(BN) { mystack.push(BN); std::cout<<BN->data<<" "; BN=BN->lChild; } BN=mystack.top(); mystack.pop(); BN=BN->rChild; } }
中序遍历和前序遍历,不管是递归还是非递归,都只有一句代码的位置的区别
Inorder traversal:
D B E F A G H C I
//递归中序遍历
void RecursionPreOrderTraversal(BiTree bitree)
{
if(bitree)
{
RecursionPreOrderTraversal(bitree->lChild);
std::cout<<bitree->data<<" ";
RecursionPreOrderTraversal(bitree->rChild);
}
}
//非递归中序遍历 void NonRecursionInOrderTraversal(BiTree bitree) { BiNode* BN=bitree; std::stack<BiNode *> mystack; while(BN||!mystack.empty()) { while(BN) { mystack.push(BN); BN=BN->lChild; } BN=mystack.top(); mystack.pop(); std::cout<<BN->data<<" "; BN=BN->rChild; } }
Postorder traversal:
D E F B H G I C A
与前序遍历、后序遍历套路相同
//递归后序遍历
void RecursionPostOrderTraversal(BiTree bitree)
{
if(bitree)
{
RecursionPostOrderTraversal(bitree->lChild);
RecursionPostOrderTraversal(bitree->rChild);
std::cout<<bitree->data<<" ";
}
}
主要思路:
//非递归后序遍历 void NonRecursionPostOrderTraversal(BiTree bitree) { BiNode* BN=bitree; std::stack<BiNode*> mystack; std::stack<BiNode *> resultstack; //效仿非递归的前序遍历,访问所有元素 while(BN||!mystack.empty()) { while(BN) { mystack.push(BN);//第一次访问该元素时,存储进resultstack resultstack.push(BN); BN=BN->rChild; } BN=mystack.top(); mystack.pop(); BN=BN->lChild; } //依次出栈resultstack中的元素 while(!resultstack.empty()) { std::cout<<resultstack.top()->data<<" "; resultstack.pop(); } }
主要思路:
队列实现:遍历从根结点开始,首先将根结点入队,然后开始执行循环:结点出队、访问该结点、其左右儿子入队
Level Order Traversal:
A B C D F G I E H
//层次遍历 void LevelOrderTraversal(BiTree bitree) { std::queue<BiNode *> myqueue; BiNode * BN=bitree; if(BN) { myqueue.push(BN); while(!myqueue.empty()) { BN=myqueue.front(); std::cout<<BN->data<<" "; myqueue.pop(); if(BN->lChild) { myqueue.push(BN->lChild); } if(BN->rChild) { myqueue.push(BN->rChild); } } } }
int main() { BiTree binary_tree=createTree("data.txt"); std::cout<<"Preoreder traversal:\n"; NonRecursionPreOrderTraversal(binary_tree); std::cout<<"\nInorder traversal:\n"; NonRecursionInOrderTraversal(binary_tree); std::cout<<"\nPostorder traversal:\n"; NonRecursionPostOrderTraversal(binary_tree); std::cout<<"\nLevel Order Traversal:\n"; LevelOrderTraversal(binary_tree); std::cout<<"\nPrint Leaves:\n"; PreOrderPrintLeaves(binary_tree); std::cout<<"\nGet Height:\n"; int height=PostOrderGetHeight(binary_tree); std::cout<<height; std::cout<<"\nGet Height:\n"; int height=BreathFirstGetHeight(binary_tree); std::cout<<height; return 0; }
在二叉树的遍历算法中增加检测结点的“左右子树是否都为空”。
//输出二叉树的叶子结点
void PreOrderPrintLeaves(BiTree bitree)
{
if(bitree)
{
if(!bitree->lChild&&!bitree->rChild)
{
std::cout<<bitree->data<<" ";
}
PreOrderPrintLeaves(bitree->lChild);
PreOrderPrintLeaves(bitree->rChild);
}
}
//得到树的深度 后序遍历算法 //时间复杂度O(n) int PostOrderGetHeight(BiTree bitree) { if(bitree) { int lHeight,rHeight,maxHeight; lHeight=PostOrderGetHeight(bitree->lChild); rHeight=PostOrderGetHeight(bitree->rChild); maxHeight=lHeight>=rHeight?lHeight+1:rHeight+1; return maxHeight; } else { return 0; } }
//层次遍历获得树高度 //需要一辅助变量保存当前层的节点个数 int BreathFirstGetHeight(BiTree bitree) { BiNode* BN = bitree; queue<BiNode*> myqueue; int height = 0; int nodesize = 0; if (BN) { myqueue.push(BN); nodesize = myqueue.size(); while (!myqueue.empty()) { while (nodesize > 0) { BN = myqueue.front(); myqueue.pop(); if (BN->lChild) { myqueue.push(BN->lChild); } if (BN->rChild) { myqueue.push(BN->rChild); } nodesize--; } height++; nodesize = myqueue.size(); } } return height; }
前序中序或中序后序
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。