一 遍历
(1)二叉树的遍历:
遍历方式:先序、中序、后序和层次(熟记:三个递归算法+三个非递归算法+层次遍历算法)
时间复杂度:遍历二叉树的算法中的基本操作都是访问节点,且不论按哪一种次序进行遍历,对含有n个结点的二叉树,其时间复杂度为O(n)。
空间复杂度:为遍历过程中栈的最大容量,即树的深度,最坏情况下为n,则空间复杂度为O(n)。
(2)树的遍历:
树有两种次序遍历方法:先根次序遍历树和后根次序遍历树。
当树采用二叉链表作为存储结构时,树的先根和后根遍历可借用二叉树的先序遍历和中序遍历实现。
(3)森林的两种遍历算法:
森林的先序和中序遍历对应于二叉树的二叉树的先序和中序遍历。
二 二叉树、树与森林间的转换
(1)二叉树与树的转换:
由于二叉树与树都可用二叉链表作为存储结构,则以二叉链表作为媒介可导出树与二叉树之间的一个对应关系。也就是说给定一棵树,可以找到唯一的一棵二叉树与之对应。
如下图:
(2)二叉树与森林的转换:
任何一棵树对应的二叉树的根节点的右子树必空。若把第二棵树的根节点看成是第一棵树的根节点的兄弟,则同样可导出森林与二叉树的对应关系。
如下如:
三 二叉树遍历代码:
#include<iostream>
#include<queue>
#include<stack>
#include<set>
using namespace std;
struct BTNode
{
int data;
BTNode *left,*right;
bool visit;
};
/*先序创建二叉树*/
void create_binary(BTNode *&root)
{
int data;
cin>>data;
if(data==0)
return;
if((root=(struct BTNode*)malloc(sizeof(BTNode)))==NULL)
return;
root->data=data;
root->visit=false;
root->left=root->right=NULL;
create_binary(root->left);
create_binary(root->right);
}
/*递归遍历*/
void PreOrderTraverse(BTNode *root)
{
if(root==NULL)return;
else
{
cout<<root->data<<endl;
PreOrderTraverse(root->left);
PreOrderTraverse(root->right);
}
}
void InOrderTraverse(BTNode *root)
{
if(root==NULL)
return;
else
{
InOrderTraverse(root->left);
cout<<root->data<<endl;
InOrderTraverse(root->right);
}
}
void PostOrderTraverse(BTNode *root)
{
if(root==NULL)
return;
else
{
PostOrderTraverse(root->left);
PostOrderTraverse(root->right);
cout<<root->data<<endl;
}
}
void LevelTraverse(BTNode*root)
{
if(root==NULL)return;
queue<BTNode*>que;
que.push(root);
while(!que.empty())
{
BTNode *ptr=que.front();
cout<<ptr->data<<endl;
que.pop();
if(ptr->left)que.push(ptr->left);
if(ptr->right)que.push(ptr->right);
}
}
/*非递归遍历:前序容易,其余麻烦*/
void PreOrderTraverse1(BTNode *root)
{
if(root==NULL)return;
stack<BTNode *>stk;
stk.push(root);
while(!stk.empty())
{
BTNode *ptr=stk.top();stk.pop();
cout<<ptr->data<<endl;
if(ptr->right)stk.push(ptr->right);
if(ptr->left)stk.push(ptr->left);
}
}
/*注意*/
void InOrderTraverse1(BTNode *root)
{
/*数据结构写法,优先选择、
if(root==NULL)return;
stack<BTNode*> stk;
stk.push(root);
while(!stk.empty())
{
BTNode *ptr=stk.top();
while(ptr){stk.push(ptr->left);ptr=ptr->left;}
stk.pop();
if(!stk.empty())
{
ptr=stk.top();
cout<<ptr->data<<endl;
stk.pop();
stk.push(ptr->right);
}
}
*/
//加标记法:在节点添加成员,或者利用set存储加入stack的节点,然后每次加入的时候进行判断。
//(简单,但效率不高,脑子不转时用)
/*if(root==NULL)return;
stack<BTNode*>stk;stk.push(root);
root->visit=true;//visit代表有没有进过栈。
while(!stk.empty())
{
BTNode *ptr=stk.top();
while(ptr->left&&!ptr->left->visit){stk.push(ptr->left);ptr->left->visit=true;ptr=ptr->left;}
if(!stk.empty())
{
ptr=stk.top();
cout<<ptr->data<<endl;
stk.pop();
if(ptr->right)stk.push(ptr->right);
}
}*/
/*这个方法可行,但是是一次性的,因为破坏了二叉树的结构,不要用。
if(root==NULL)return;
stack<BTNode*>stk;stk.push(root);
while(!stk.empty())
{
BTNode *ptr=stk.top();
while(ptr->left){stk.push(ptr->left);ptr->left=NULL;ptr=stk.top();}
if(!stk.empty())
{
ptr=stk.top();
cout<<ptr->data<<endl;
stk.pop();
if(ptr->right)stk.push(ptr->right);
}
}
*/
}
void PostOrderTraverse1(BTNode *root)
{
/*某人做法:比较好*/
/*
stack<BTNode*> s;
BTNode *cur; //当前结点
BTNode *pre=NULL; //前一次访问的结点
s.push(root);
while(!s.empty())
{
cur=s.top();
if((cur->left==NULL&&cur->right==NULL)||
(pre!=NULL&&(pre==cur->left||pre==cur->right)))
{
cout<<cur->data<<endl; //如果当前结点没有孩子结点或者孩子节点都已被访问过
s.pop();
pre=cur;
}
else
{
if(cur->right!=NULL)
s.push(cur->right);
if(cur->left!=NULL)
s.push(cur->left);
}
}*/
//利用辅助存储标记节点是否进过栈。(简单,但效率不高,脑子不转时用)
/*if(root==NULL)return;
stack<BTNode*>stk;stk.push(root);
root->visit=true;
while(!stk.empty())
{
BTNode *ptr=stk.top();
while(ptr->left&&!ptr->left->visit){stk.push(ptr->left);ptr->left->visit=true;ptr=ptr->left;}
if(!stk.empty())
{
ptr=stk.top();
if(ptr->right&&!ptr->right->visit)
{
stk.push(ptr->right);
ptr->right->visit=true;
}
else
{cout<<ptr->data<<endl;stk.pop();}
}
}*/
//利用辅助存储标记节点是否进过栈。(简单,但效率不高,脑子不转时用)
/*if(root==NULL)return;
stack<BTNode*>stk;stk.push(root);
set<BTNode*>node_set;
node_set.insert(root);
while(!stk.empty())
{
BTNode *ptr=stk.top();
while(ptr->left&&!node_set.count(ptr->left)){stk.push(ptr->left);node_set.insert(ptr->left);ptr=ptr->left;}
if(!stk.empty())
{
ptr=stk.top();
if(ptr->right&&!node_set.count(ptr->right))
{
stk.push(ptr->right);
node_set.insert(ptr->right);
}
else
{cout<<ptr->data<<endl;stk.pop();}
}
}*/
/*一次性算法,不要用,仅作参考。
if(root==NULL)return;
stack<BTNode*> stk;
stk.push(root);
while(!stk.empty())
{
BTNode *ptr=stk.top();
while(ptr->left){stk.push(ptr->left);ptr->left=NULL;ptr=stk.top();}
if(!stk.empty())
{
ptr=stk.top();
if(ptr->right==NULL){cout<<ptr->data<<endl;stk.pop();}
else{stk.push(ptr->right);ptr->right=NULL;}
}
}*/
}
int main()
{
BTNode *root;
create_binary(root);
cout<<"递归:"<<endl;
cout<<"先序:"<<endl;
PreOrderTraverse(root);
cout<<"中序:"<<endl;
InOrderTraverse(root);
cout<<"后序:"<<endl;
PostOrderTraverse(root);
cout<<"层次"<<endl;
LevelTraverse(root);
cout<<"非递归:"<<endl;
cout<<"先序:"<<endl;
PreOrderTraverse1(root);
cout<<"中序:"<<endl;
InOrderTraverse1(root);
cout<<"后序:"<<endl;
PostOrderTraverse1(root);
}