二叉树结点的表示:
采用链表的存储方式,设有数据域和左右孩子指针
代码实现:
typedef struct BiNode{
ElemType data;
struct BiNode *lchild,*rchild; //左孩子,右孩子
}BiNode,*BiTree;
二叉树的建立:
前序遍历输入结点
代码实现:
//建立二叉树
void CreateTree(BiTree &T){
ElemType c;
scanf("%c",&c);
if(c=='#'){
T=NULL;
return;
}
else{
T=(BiTree)malloc(sizeof(BiNode)); //开辟动态空间
T->data=c;
CreateTree(T->lchild);
CreateTree(T->rchild);
}
}
前序遍历:
先输出根结点,依次遍历左子树和右子树
递归版本容易理解,在非递归版本中借用栈的特性来实现,思路是从根结点开始有左孩子就让左孩子进栈,之后跳出循环
如果栈不空输出栈顶元素,紧接着当前节点指向其右孩子,在返回循环让所有左孩子进栈
代码实现:
//先根递归遍历
void PreOrder(BiTree T){
if(T){
printf("%c ",T->data);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
//先根非递归遍历
void FPreOrder(BiTree T){
stack<BiTree> s;
BiTree cur=T;
while(cur||!s.empty()){ //树不空或栈不空
while(cur){ //从根节点一直往下遍历当前结点的左孩子,没有时跳出
cout<<cur->data<<" "; //输出根节点
s.push(cur); //同时入栈
cur=cur->lchild; //指向当前结点的左孩子
}
if(!s.empty()){
cur=s.top(); //当前结点指向栈顶元素
s.pop(); //出栈
cur=cur->rchild; //寻找其右孩子
}
}
}
中序遍历:
先遍左子树,再根结点,最后右子树
在非递归版本中思想同先序遍历的相同,只是注意结点数据的输出位置不同,其他的都一样
代码实现:
void InOrder(BiTree T){
if(T){
InOrder(T->lchild);
printf("%c ",T->data);
InOrder(T->rchild);
}
}
void FInOrder(BiTree T){
stack<BiTree> s;
BiTree cur=T;
while(cur||!s.empty()){
while(cur){ //从根节点一直往下遍历当前节点的左孩子,没有时跳出
s.push(cur);
cur=cur->lchild;
}
if(!s.empty()){
cur=s.top();
cout<<cur->data<<" ";
s.pop();
cur=cur->rchild;
}
}
}
后序遍历:
先左子树,再右子树,最后根节点
在非递归版本中,刚开始从根节点开始有左孩子就让左孩子进栈,否则右孩子进栈,然后令当前结点指向栈顶元素,输出对应的数据后出栈,若当前结点是此时栈顶元素的左孩子,则让当前结点指向其右孩子,实现左右中的遍历顺序,若不是,证明当前结点是此时栈顶元素的右孩子,使当前节点为NULL,在下一次循环中直接输出双亲的数据
代码实现:
void PostOrder(BiTree T){
if(T){
PostOrder(T->lchild);
PostOrder(T->rchild);
printf("%c ",T->data);
}
}
void FPostOrder(BiTree T){
stack<BiTree> s;
BiTree cur=T;
while(cur||!s.empty()){
while(cur){
s.push(cur);
cur=cur->lchild?cur->lchild:cur->rchild; //左孩子先进,右孩子后进
}
cur=s.top();
cout<<cur->data<<" ";
s.pop();
if(!s.empty()&&cur==(s.top())->lchild)
cur=(s.top())->rchild;
else
cur=NULL;
}
}
层序遍历:
即从上到下,从左到右依次输出元素值
很明显将二叉树中的元素按照对应顺序放入队列,然后输出队列里的值就行
代码实现:
void SeqOrder(BiTree T){
queue<BiTree> q;
if(T){
q.push(T); //根节点入队
}
while(!q.empty()){
cout<<q.front()->data<<" "; //输出队头元素
if(q.front()->lchild){
q.push(q.front()->lchild); //左孩子入队
}
if(q.front()->rchild){
q.push(q.front()->rchild); //右孩子入队
}
q.pop(); //输出过的元素对应结点出队
}
}
完整代码:
#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstdlib>
using namespace std;
typedef char ElemType; //自定义结点数据类型
//建立二叉链表
typedef struct BiNode{
ElemType data;
struct BiNode *lchild,*rchild; //左孩子,右孩子
}BiNode,*BiTree;
//建立二叉树
void CreateTree(BiTree &T){
ElemType c;
scanf("%c",&c);
if(c=='#'){
T=NULL;
return;
}
else{
T=(BiTree)malloc(sizeof(BiNode)); //开辟动态空间
T->data=c;
CreateTree(T->lchild);
CreateTree(T->rchild);
}
}
//先根递归遍历
void PreOrder(BiTree T){
if(T){
printf("%c ",T->data);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
//先根非递归遍历
void FPreOrder(BiTree T){
stack<BiTree> s;
BiTree cur=T;
while(cur||!s.empty()){ //树不空或栈不空
while(cur){ //从根节点一直往下遍历当前结点的左孩子,没有时跳出
cout<<cur->data<<" "; //输出根节点
s.push(cur); //同时入栈
cur=cur->lchild; //指向当前结点的左孩子
}
if(!s.empty()){
cur=s.top(); //当前结点指向栈顶元素
s.pop(); //出栈
cur=cur->rchild; //寻找其右孩子
}
}
}
void InOrder(BiTree T){
if(T){
InOrder(T->lchild);
printf("%c ",T->data);
InOrder(T->rchild);
}
}
void FInOrder(BiTree T){
stack<BiTree> s;
BiTree cur=T;
while(cur||!s.empty()){
while(cur){ //从根节点一直往下遍历当前节点的左孩子,没有时跳出
s.push(cur);
cur=cur->lchild;
}
if(!s.empty()){
cur=s.top();
cout<<cur->data<<" ";
s.pop();
cur=cur->rchild;
}
}
}
void PostOrder(BiTree T){
if(T){
PostOrder(T->lchild);
PostOrder(T->rchild);
printf("%c ",T->data);
}
}
void FPostOrder(BiTree T){
stack<BiTree> s;
BiTree cur=T;
while(cur||!s.empty()){
while(cur){
s.push(cur);
cur=cur->lchild?cur->lchild:cur->rchild; //左孩子先进,右孩子后进
}
cur=s.top();
cout<<cur->data<<" ";
s.pop();
if(!s.empty()&&cur==(s.top())->lchild)
cur=(s.top())->rchild;
else
cur=NULL;
}
}
void SeqOrder(BiTree T){
queue<BiTree> q;
if(T){
q.push(T); //根节点入队
}
while(!q.empty()){
cout<<q.front()->data<<" "; //输出队头元素
if(q.front()->lchild){
q.push(q.front()->lchild); //左孩子入队
}
if(q.front()->rchild){
q.push(q.front()->rchild); //右孩子入队
}
q.pop(); //输出过的元素对应结点出队
}
}
int main(){
BiTree T=NULL;
//printf("前序遍历输入结点:\n");
CreateTree(T);
//printf("前序遍历:\n");
PreOrder(T);
cout<<endl;
FPreOrder(T);
cout<<endl;
//printf("中序遍历:\n");
InOrder(T);
cout<<endl;
FInOrder(T);
cout<<endl;
//printf("后序遍历:\n");
PostOrder(T);
cout<<endl;
FPostOrder(T);
cout<<endl;
//printf("层序遍历:\n");
SeqOrder(T);
cout<<endl;
return 0;
}