二叉树的建立和遍历的各种问题
链表声明:
点击查看代码
//基本结构声明
#include<iostream>
#include<queue>
#include<stack>
#include<cstdio>
#define NoInfo 0 // 0表示没有结点
using namespace std;
typedef int ElementType;
typedef struct TNode* Position;
typedef Position BinTree;
//二叉树链表结构
struct TNode{
ElementType Data; //结点数据
BinTree Left; //左子树
BinTree Right; //右子树
};
1.先序建立二叉树
点击查看代码
//先序建立二叉树
BinTree CreateBinTree(){
ElementType data;
scanf("%d",&data);
if(data==NoInfo) return NULL;
BinTree P;
P=new TNode;
P->Data=data;
P->Left=CreateBinTree();
P->Right =CreateBinTree();
return P;
}
2.层序建立二叉树
点击查看代码
//层序建立二叉树
BinTree CreateBinTree(){
ElementType data;
BinTree BT,T;
queue<BinTree> q;//创建队列
scanf("%d",&data);
if(data!=NoInfo){
BT=new TNode;
BT->Data =data;
BT->Left =BT->Right =NULL;
q.push(BT);
}
else return NULL;//第一个数据为0则返回空树
while(!q.empty()){
T=q.front();//取出结点
q.pop();
scanf("%d",&data);//读入T的左孩子
if(data==NoInfo) T->Left =NULL;
else{
T->Left =new TNode;
T->Left ->Data=data;
T->Left ->Left=T->Left ->Right=NULL;
q.push(T->Left );
}
scanf("%d",&data);//读入T的右孩子
if(data==NoInfo) T->Right =NULL;
else{
T->Right =new TNode;
T->Right ->Data=data;
T->Right ->Left=T->Right ->Right=NULL;
q.push(T->Right );
}
}
return BT;
}
3.递归先序遍历
点击查看代码
void PreorderTraversal_1(BinTree BT){
if(BT){
printf("%d",BT->Data );
PreorderTraversal_1(BT->Left );
PreorderTraversal_1(BT->Right );
}
}
4.非递归先序遍历
点击查看代码
void PreorderTraversal_2(BinTree BT){
BinTree T=BT;
stack<BinTree> s;
while(T||!s.empty()){
while(T){
printf("%d",T->Data );
s.push(T);
T=T->Left ;
}
T=s.top();
s.pop();
T=T->Right ;
}
}
5.递归中序遍历
点击查看代码
void InorderTraversal_1(BinTree BT){
if(BT){
InorderTraversal_1(BT->Left );
printf("%d",BT->Data );
InorderTraversal_1(BT->Right );
}
}
6.非递归中序遍历
点击查看代码
//非递归中序遍历
void InorderTraversal_2(BinTree BT){
BinTree T=BT;
stack<BinTree> s;
while(T||!s.empty()){
while(T){
s.push(T);
T=T->Left ;
}
T=s.top();
s.pop();
printf("%d",T->Data );
T=T->Right ;
}
}
7.递归后序遍历
点击查看代码
//递归后序遍历
void PostorderTraversal_1(BinTree BT){
if(BT){
PostorderTraversal_1(BT->Left );
PostorderTraversal_1(BT->Right );
printf("%d",BT->Data );
}
}
8.非递归后序遍历
点击查看代码
//非递归后序遍历
void PostorderTraversal_2(BinTree BT){
BinTree T,Pre=NULL;
stack<BinTree> s;
s.push(BT);
while(!s.empty()){
T=s.top();
if( (T->Left ==NULL&&T->Right ==NULL) ||
(Pre!=NULL&& (T->Left==Pre ||T->Right==Pre ) ) ){
printf("%d",T->Data );
s.pop();
Pre=T;
}
else{
if(T->Right !=NULL) s.push(T->Right );
if(T->Left !=NULL) s.push(T->Left );
}
}
}
9.层序遍历
点击查看代码
void LevelorderTravelsal(BinTree BT){
queue<BTree> q;
BinTree T;
if(!BT) return;
q.push(BT);
while(!q.empty()){
T=q.front();
q.pop();
printf("%d ",T->Data);
if(T->Left ) q.push(T->Left );
if(T->Right ) q.push(T->Right );
}
}
10.二叉树高度
点击查看代码
//二叉树高度
int GetHeight(BinTree BT){
if(BT) return max(GetHeight(BT->Left),GetHeight(BT->Right ))+1;
else return 0;//空树高度为0
}
11.求二叉树所有结点
点击查看代码
//求二叉树所有结点
int CountNode(BinTree BT){
if(BT) return CountNode(BT->Left )+CountNode(BT->Right )+1;
else return 0;
}
12.求二叉树叶子结点
点击查看代码
void LeaveCount(BinTree BT){
if(BT){
if(BT->Left ==NULL&&BT->Right ==NULL)
count++;
LeaveCount(BT->Left );
LeaveCount(BT->Right );
}
}
int LeafcountofBinTree(BinTree BT){
if(BT){
if(BT->Left ==NULL&&BT->Right ==NULL)
return LeafcountofBinTree(BT->Left )+LeafcountofBinTree(BT->Right )+1;
}
else return 0;
}
13.先序输出二叉树叶子结点
点击查看代码
void PreorderPrintLeaves(BinTree BT){
if(BT!=NULL){
if((BT->Left==NULL)&&(BT->Right==NULL))
printf(" %c",BT->Data);
PreorderPrintLeaves(BT->Left);
PreorderPrintLeaves(BT->Right);
}
}
14.镜面反转,将所有非叶结点的左右孩子对换
点击查看代码
void Inversion(BinTree BT){
if(BT){
Inversion(BT->Left);
Inversion(BT->Right);
BinTree temp;
temp=BT->Left ;
BT->Left =BT->Right ;
BT->Right =temp;
}
}
15.销毁二叉树
点击查看代码
void DestroyBinTree(BinTree BT){
if(BT){
DestroyBinTree(BT->Left );
DestroyBinTree(BT->Right );
delete BT;
BT=NULL;
}
}
16.根据前序和中序遍历还原二叉树
点击查看代码
//根据前序和中序遍历还原二叉树
BinTree PreInoRestoreBinTree(int* inorder ,int* preorder, int length)
{
if(length==0) return NULL;
BinTree T=new TNode;
int rootIndex;
T->Data = *preorder;
for(rootIndex=0;rootIndex < length; rootIndex++)
if(inorder[rootIndex] == *preorder)
break;
T->Left = PreInoRestoreBinTree(inorder,preorder +1 , rootIndex);
T->Right = PreInoRestoreBinTree(inorder + rootIndex + 1 ,preorder + rootIndex + 1 , length - (rootIndex + 1));
return T;
}
17.根据后序和中序遍历还原二叉树
点击查看代码
BinTree InoPosRestoreBinTree(int *inorder,int *postorder,int length)
{
if(length==0) return NULL;
BinTree T;
int rootindex;
T =new TNode;
T->Data=postorder[length-1];
T->Left=T->Right=NULL;
for(rootindex=0; rootindex < length; rootindex++)
if(inorder[rootindex] == postorder[length-1])
break;
T->Left =InoPosRestoreBinTree(inorder,postorder,rootindex);
T->Right =InoPosRestoreBinTree(inorder+rootindex+1,postorder+rootindex,length-(rootindex+1));
return T;
}
17.1 根据中序和后序输出前序
点击查看代码
#include<iostream>
#include<vector>
#include<string>
using namespace std;
string in, post, ans="";
void pre(int root, int l, int r){
if(l>r) return ;
int i=l;
while(in[i] != post[root]) i++;
//printf("%d %d %d %d\n",root,l,r,i);
ans += post[root];
//cout<<"L"<<endl;
pre(root-r+i-1, l, i-1);
//cout<<"R"<<endl;
pre(root-1, i+1, r);
}
int main(){
cin>>in>>post;
pre(post.size()-1,0,post.size()-1);
cout<<ans<<endl;
return 0;
}
人生不如意的时候,是上帝给的长假,这个时候应该好好享受假期。
突然有一天假期结束,时来运转,人生才是真正开始了。
突然有一天假期结束,时来运转,人生才是真正开始了。