创建一颗二叉树,需要掌握一些基本操作,如,创建树,前序遍历,中序遍历,后序遍历,利用非递归方式的前序遍历,中序遍历,后序遍历,利用非递归方式原理大致相同,利用栈的先进后出原理即可实现,层序遍历,是从左到右遍历,利用队列先进先出的原理即可实现,计算叶子节点,二叉树的深度,交换左右子树等基本操作。
创造一棵二叉树是所需要的头文件和结构体
#include<stdio.h>
#include<stdlib.h>#include<stack>
#include<queue>
#include <iostream>
using namespace std;
typedef int ElementType;
typedef struct TreeNode{
ElementType Element;
struct TreeNode *left;
struct TreeNode *right;
}TreeNode,*SearchTree;//定义结构体节点
1.建立一颗二叉树,及插入新的元素
二叉树的左结点的数小于根节点的数值得大小,当插入一个新的元素时,如果该节点部位空,则判断新元素的数值是否大于该结点的数值得大小,直到最后节点为空。
2.利用递归对该二叉树进行前序遍历
前序遍历:根左右
判断该节点是否为空,不为空,就将该节点的值打印出来,然后将左子树的再次进行相同的遍历,遍历到最后,然后就可以进行最后一个节点的右子树的遍历,直到所有的栈全部结束,则遍历结束
3.非递归的前序遍历,用栈进行二叉树的先序遍历; 将二叉树的左结点全部打印出来,直到最后一个,然后再把最后一个节点来判断其是否有右节点,再次循环,直到最后,栈为空,退出循环,遍历结束,代码如下。
4.利用递归来进行中序遍历,中序遍历,所以是左根右
5.非递归方式来进行中序遍历
将左节点存储到栈里面,直到最后一个最左的左结点,然后打印出该元素,检查该节点是否有右子树,有的话就再进行while循环,这时我们假设没有右子树,则从栈里拿出元素,进行打印,然后判断其有没有右子树,此时我们假设该右子树有一个元素,则将其放到栈里面,此时循环结束,然后再将其打印出来,便完成了对这个左子树的遍历,依次类推。这个过程就是利用了栈的后进先出的思想,将右子树的元素放进去,能够先打印出来
6.使用递归完成后续遍历,后续遍历:左右根。
7.层序遍历
}//查找元素
7.计算叶子节点数,利用递归,直到最后的左右节点均为空时,则叶子结点数目加一,依次类推,得出叶子节点数
8.计算二叉树的深度:利用递归,直到左子树为空时,这个左子树的递归便结束,然后便可二叉树的左子树深度加一,总而言之,二叉树的深度是从下而上进行计算的
}//计算该树的深度
int Swap(SearchTree T)
{
TreeNode *tmp;
stack<TreeNode *>p1;
if(T==NULL)
return 0;
while(1)
{
tmp=T->left;
T->left=T->right;
T->right=tmp;//先将左右子树进行交换
if(T->right!=NULL)//先进行左子树的交换,此时的右子树是本来的左子树;
{
p1.push(T->right);//将右子树放到栈里面
}
if(T->left!=NULL)
{
T=T->left;
}
else
{
if(!p1.empty())
{
T=p1.top();
p1.pop();
}
else
break;
}
}
}//利用栈进行二叉树左右子树的交换
int main()
{
SearchTree T=NULL;//创造一棵树
int e=0,m,n,i,depth,counts;
cin>>n;
for(i=0;i<n;i++)
{
cin>>e;
Create_Insert(T,e);
}//输入n个节点
PreOrderTraverse(T);//对该二叉树的前序遍历
printf("\n");
InOrderTraverse(T);//对该二叉树的中序遍历
printf("\n");
PostOrderTraverse(T);//对该二叉树的后序遍历
printf("\n");
cin>>m;
n=Search(T,m);//查找该二叉树里面有无m这个元素
cout<<n<<endl;
cin>>m;
n=Search(T,m);//查找该二叉树里面有无m这个元素
cout<<n<<endl;
cin>>e;
Create_Insert(T,e);//插入元素e;
PreOrderTraverse(T);//对插入新元素的二叉树的前序遍历
printf("\n");
InOrderTraverse(T);//对插入新元素的二叉树的中序遍历
printf("\n");
PostOrderTraverse(T);//对插入新元素的二叉树的后序遍历
printf("\n");
InOrderTraverse2(T);//对插入新元素的二叉树的中序遍历(非递归方式)
printf("\n");
leveltraversal(T);//对插入新元素的二叉树的层序遍历
printf("\n");
Swap(T);//交换左右子树
PreOrderTraverse(T);//交换左右子树后的二叉树的前序遍历
printf("\n");
InOrderTraverse(T);//交换左右子树后的二叉树的中序遍历
printf("\n");
PostOrderTraverse(T);//交换左右子树后的二叉树的后序遍历
printf("\n");
Swap(T);//对该子树再次进行左右子树交换
PreOrderTraverse(T);//再次交换左右子树后的二叉树的前序遍历
printf("\n");
InOrderTraverse(T);//再次交换左右子树后的二叉树的中序遍历
printf("\n");
PostOrderTraverse(T);//再次交换左右子树后的二叉树的后序遍历
printf("\n");
n=Depth(T,depth);//二叉树的深度
cout<<n<<endl;
n=Leavecount(T,counts);//二叉树的叶子节点数
cout<<n<<endl;
return 0;
}
具体实现代码:#include<stdio.h>
#include<stdlib.h>
#include<stack>
#include<queue>
#include <iostream>
using namespace std;
typedef int ElementType;
typedef struct TreeNode{
ElementType Element;
struct TreeNode *left;
struct TreeNode *right;
}TreeNode,*SearchTree;//定义结构体节点
SearchTree Create_Insert(SearchTree &T,ElementType e)
{
//二叉排序树的插入过程
if(!T)
{
//未找到值为e的结点,就新生成一个结点
T = (TreeNode*)malloc(sizeof(TreeNode));
T->Element = e;
T->left = NULL;
T->right = NULL;
}
else if(e<T->Element) //在左子树中插入
Create_Insert(T->left,e);
else if(e>T->Element) //在右子树中插入
Create_Insert(T->right,e);
}
int PreOrderTraverse(SearchTree T)
{
if(T!=NULL)
{
printf("%d ",T->Element);//将根节点打印出来;
PreOrderTraverse(T->left);
PreOrderTraverse(T->right);
}//先序遍历;
}
int PreOrderTraverse2(SearchTree T)//非递归的前序遍历,用栈进行二叉树的先序遍历
{
TreeNode *p1,*top;
stack<TreeNode *>p;
p1=T;
while(p1||!p.empty())
{
while(p1)
{
printf("%d",T->Element);
p.push(p1);
p1=p1->left;
}//循环,将整棵树的左结点进行打印出来
top=p.top();
p.pop();
p1=top->right;//最后一个节点里面有没有右子树,有的话再次进行循环
}
}
int InOrderTraverse(SearchTree T)
{
if(T!=NULL)
{
InOrderTraverse(T->left);
printf("%d ",T->Element);
InOrderTraverse(T->right);
}
}//运用递归进行中序遍历
int InOrderTraverse2(SearchTree T)
{
TreeNode *p1,*top;
stack<TreeNode *> p;
p1=T;
while(p1||!p.empty())
{
while(p1)
{
p.push(p1);
p1=p1->left;
}//将最左边的节点全部存储到栈里面
top=p.top();
printf("%d ",top->Element);
p.pop();
p1=top->right;
}//非递归中序遍历
}//用栈进行中序遍历
int PostOrderTraverse(SearchTree T)
{
if(T!=NULL)
{
PostOrderTraverse(T->left);
PostOrderTraverse(T->right);
printf("%d ",T->Element);
}
}//后序遍历
int leveltraversal(SearchTree T)
{
queue<TreeNode *> p;
TreeNode *top;
p.push(T);
while(!p.empty())
{
top=p.front();
p.pop();
printf("%d ",top->Element);//按照队列先进先出进行输出;
if(top->left!=NULL)//进入队列里面,都是从左到右入队
p.push(top->left);
if(top->right!=NULL)
p.push(top->right);
}
}//用队列进行层序遍历
int Search(SearchTree T,int &e)
{
if(T!=NULL)
{
if(T->Element>e)//e小于该根节点,便查找左子树
{
Search(T->left,e);
}
if(T->Element<e)//e大于该根节点,便查找右子树
{
Search(T->right,e);
}
if(T->Element==e)//e等于该根节点的值
{
e=1;
return e;
}
}
else
e=0;
return e;
}//查找元素
int Leavecount(SearchTree T,int &counts)
{
if(T==NULL)//这颗树是空的
return 0;
counts=0;
if(T->left==NULL||T->right==NULL)
{
counts++;//当该节点的左右节点均为空时;
}
else
{
counts=Leavecount(T->left,counts)+Leavecount(T->right,counts);
//每颗子树上面都有左右节点,直到最后左右节点都为空
}
return counts;
}//计算该二叉树的叶子节点数
int Depth(SearchTree T,int &depth)
{
depth=0;
if(T!=NULL)
{
int ldepth=Depth(T->left,depth)+1;
int rdepth=Depth(T->right,depth)+1;
depth=(ldepth>rdepth)?ldepth:rdepth;
}
return depth;
}//计算该树的深度
int Swap(SearchTree T)
{
TreeNode *tmp;
stack<TreeNode *>p1;
if(T==NULL)
return 0;
while(1)
{
tmp=T->left;
T->left=T->right;
T->right=tmp;//先将左右子树进行交换
if(T->right!=NULL)//先进行左子树的交换,此时的右子树是本来的左子树;
{
p1.push(T->right);//将右子树放到栈里面
}
if(T->left!=NULL)
{
T=T->left;
}
else
{
if(!p1.empty())
{
T=p1.top();
p1.pop();
}
else
break;
}
}
}//利用栈进行二叉树左右子树的交换
int main()
{
SearchTree T=NULL;//创造一棵树
int e=0,m,n,i,depth,counts;
cin>>n;
for(i=0;i<n;i++)
{
cin>>e;
Create_Insert(T,e);
}//输入n个节点
PreOrderTraverse(T);//对该二叉树的前序遍历
printf("\n");
InOrderTraverse(T);//对该二叉树的中序遍历
printf("\n");
PostOrderTraverse(T);//对该二叉树的后序遍历
printf("\n");
cin>>m;
n=Search(T,m);//查找该二叉树里面有无m这个元素
cout<<n<<endl;
cin>>m;
n=Search(T,m);//查找该二叉树里面有无m这个元素
cout<<n<<endl;
cin>>e;
Create_Insert(T,e);//插入元素e;
PreOrderTraverse(T);//对插入新元素的二叉树的前序遍历
printf("\n");
InOrderTraverse(T);//对插入新元素的二叉树的中序遍历
printf("\n");
PostOrderTraverse(T);//对插入新元素的二叉树的后序遍历
printf("\n");
InOrderTraverse2(T);//对插入新元素的二叉树的中序遍历(非递归方式)
printf("\n");
leveltraversal(T);//对插入新元素的二叉树的层序遍历
printf("\n");
Swap(T);//交换左右子树
PreOrderTraverse(T);//交换左右子树后的二叉树的前序遍历
printf("\n");
InOrderTraverse(T);//交换左右子树后的二叉树的中序遍历
printf("\n");
PostOrderTraverse(T);//交换左右子树后的二叉树的后序遍历
printf("\n");
Swap(T);//对该子树再次进行左右子树交换
PreOrderTraverse(T);//再次交换左右子树后的二叉树的前序遍历
printf("\n");
InOrderTraverse(T);//再次交换左右子树后的二叉树的中序遍历
printf("\n");
PostOrderTraverse(T);//再次交换左右子树后的二叉树的后序遍历
printf("\n");
n=Depth(T,depth);//二叉树的深度
cout<<n<<endl;
n=Leavecount(T,counts);//二叉树的叶子节点数
cout<<n<<endl;
return 0;
}