二叉树的基本操作<1>-----四种遍历

二叉树遍历详解
本文详细介绍了二叉树的四种遍历方法:先序、中序、后序及层序遍历,并提供了完整的C语言实现代码。通过具体的示例展示了每种遍历方式的特点及其应用场景。
//二叉树的操作实现
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef char TreeNodeType;
//二叉树结点结构体
typedef struct TreeNode{
TreeNodeType data;
struct TreeNode* lchild;
struct TreeNode* rchild;
}TreeNode;


//队列结构体
typedef struct queue{
int cur;
TreeNode arr[100];
int size;
}Queue;


//二叉树结点的创建
TreeNode* CreatTreeNode(TreeNodeType value){
TreeNode* new = (TreeNode*)malloc(sizeof(TreeNode));
new->data = value;
new->lchild = NULL;
new->rchild = NULL;
return new;
}


//二叉树的遍历
//方式一:先序遍历
//原理:基于二叉树的递归构造,其遍历也可以采取递归的方式,先序遍历<先访问本身结点,再访问左子树,
//最后访问右子树>
void PreOrder(TreeNode* root){
if(root == NULL){
//空树
return;
}
printf("%c ",root->data);
PreOrder(root->lchild);
PreOrder(root->rchild);
}


//先序遍历的检测函数
void textPreOrder(){
//创建二叉树
printf("\n*************%s********************\n",__FUNCTION__);
TreeNode* A = CreatTreeNode('a');
TreeNode* B = CreatTreeNode('b');
TreeNode* C = CreatTreeNode('c');
TreeNode* D = CreatTreeNode('d');
A->lchild = B;
A->rchild = C;
B->lchild = D;
PreOrder(A);
printf("\n");
return;
}


//方式二;中序遍历
//原理:同先序遍历,只是访问顺序有所差异,中序遍历<先访问左子树,再访问本身结点,最后访问右子树>
void InOrder(TreeNode* root){
if(root == NULL){
//空树
return;
}
InOrder(root->lchild);
printf("%c ",root->data);
InOrder(root->rchild);
}


//中序遍历的检测函数
void textInOrder(){
//创建二叉树
printf("\n*************%s********************\n",__FUNCTION__);
TreeNode* A = CreatTreeNode('a');
TreeNode* B = CreatTreeNode('b');
TreeNode* C = CreatTreeNode('c');
TreeNode* D = CreatTreeNode('d');
A->lchild = B;
A->rchild = C;
B->lchild = D;
InOrder(A);
printf("\n");
return;
}


//方式三:后序遍历
//原理:同先序遍历,只是访问顺序有所差异,后序遍历<先访问左子树,再访问右子树,最后访问本身结点>
void PostOrder(TreeNode* root){
if(root == NULL){
//空树
return;
}
PostOrder(root->lchild);
PostOrder(root->rchild);
printf("%c ",root->data);
}


//后序遍历的检测函数
void textPostOrder(){
//创建二叉树
printf("\n*************%s********************\n",__FUNCTION__);
TreeNode* A = CreatTreeNode('a');
TreeNode* B = CreatTreeNode('b');
TreeNode* C = CreatTreeNode('c');
TreeNode* D = CreatTreeNode('d');
A->lchild = B;
A->rchild = C;
B->lchild = D;
PostOrder(A);
printf("\n");
return;
}


//方式四:层序遍历
//原理:层序遍历与以上几种遍历方式右所不同,先序遍历是将访问结点的左子树与右子树入队,再将本身结点
//出队并访问自身结点,以此循环,直到队列为空,访问结束。
//此遍历中将会用到队列函数,故在此处将先实现队列的出队与入队操作函数的实现


//队列的入队操作
void PushQueue(Queue* head,TreeNode* value){
if(head == NULL){
//非法输入
return;
}
if(head->size>=100){
//队满
return;
}
if(value == NULL){
return;
}
head->arr[(head->size+head->cur)%100] = (*value);
++head->size;
return;
}
//队列的出队操作
void PopQueue(Queue* head){
if(head == NULL){
//非法输入
return;
}
if(head->size == 0){
//空队
return;
}
++head->cur;
--head->size;
return;
}
//获得队列的队首元素
void QueueTop(Queue*head,TreeNode* value){
if(head == NULL){
//非法输入
return;
}
if(head->size == 0){
//空队
return;
}
(*value) = head->arr[head->cur%100];
   return;
}
//层序遍历的实现
void _levelOrder(Queue* que){
TreeNode value;
if(que == NULL){
//非法输入
return;
}
while(1){
if(que->size == 0){
//空队
return;
}
QueueTop(que,&value);
printf("%c ",value.data);
PushQueue(que,value.lchild);
PushQueue(que,value.rchild);
PopQueue(que);
}
}


void levelOrder(TreeNode* root){
if(root == NULL){
//空树
return;
}
Queue que = {
0,
{0},
0
};
PushQueue(&que,root);
_levelOrder(&que);

}


//递归算法计算二叉树的特定种类的结点个数和高度 #include &lt;iostream&gt; #include &lt;string&gt; using namespace std; template &lt;typename DataType&gt; struct BiNode { //二叉树的结点结构 DataType data; BiNode&lt;DataType&gt; *lchild, *rchild; }; template &lt;typename DataType&gt; class BiTree { public: BiTree(); //构造函数,初始化一棵二叉树,其前序序列由键盘输入 ~BiTree(); //析构函数,释放二叉链表中各结点的存储空间 int CountBoth(BiNode&lt;DataType&gt; *); //递归方法计算既有左孩子又有右孩子的结点个数 int Depth(BiNode&lt;DataType&gt; *);//递归方法计算高度 int CountBoth();//调用上面的递归算法计算既有左孩子又有右孩子的结点个数 int Depth(); //调用上面的递归算法计算高度 private: BiNode&lt;DataType&gt; *root; //指向根结点的头指针 void Creat(BiNode&lt;DataType&gt; *&bt);//被构造函数调用,递归方式生成二叉树 void Release(BiNode&lt;DataType&gt; *&bt); //被析构函数调用 }; //定义类中的成员函数 //构造函数:Creat利用创建二叉树 template&lt;typename DataType&gt; BiTree&lt;DataType&gt;::BiTree() { Creat(root); } //功 能:递归方法创建一棵二叉树,由构造函数调用 template &lt;typename DataType&gt; void BiTree&lt;DataType&gt;::Creat(BiNode&lt;DataType&gt; * &bt) { DataType ch; cin&gt;&gt;ch; if (ch=="#") bt = nullptr; //创建结点值为字符串的二叉树 else { bt = new BiNode&lt;DataType&gt;; //生成一个结点 bt-&gt;data=ch; Creat(bt-&gt;lchild); //递归建立左子 Creat(bt-&gt;rchild); //递归建立右子 } } //功 能:析构函数,释放二叉链表中各结点的存储空间 template&lt;typename DataType&gt; BiTree&lt;DataType&gt;::~BiTree() { //析构函数不能带参数 Release(root); } //功 能:释放二叉树的存储空间,析构函数调用 template&lt;typename DataType&gt; void BiTree&lt;DataType&gt;::Release(BiNode&lt;DataType&gt;*&bt) { if (bt != nullptr) { Release(bt-&gt;lchild); //释放左子 Release(bt-&gt;rchild); //释放右子 delete bt; } } template &lt;typename DataType&gt; int BiTree&lt;DataType&gt;::Depth() { return Depth(root); } template &lt;typename DataType&gt; int BiTree&lt;DataType&gt;::CountBoth() { return CountBoth(root); } //请在下面补充相关算法的实现 //计算既有左孩子又有右孩子的结点个数 //求二叉树高度 // int main() { BiTree&lt;string&gt; mybit; cout&lt;&lt;mybit.CountBoth()&lt;&lt;" "&lt;&lt;mybit.Depth()&lt;&lt;endl; return 0; } 样例输入 Copy Li Sun # Zhao Zhou # # Wang # # Qian # # 样例输出 Copy 2 4将c++转译为Java
最新发布
05-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值