二叉树的遍历使用C++

先说一下下,本篇我总结的是树的存储结构和二叉树的构造与遍历代码。树的知识有点多,后期我学会了,再跟大家分享。

二叉树的存储结构

我认为用链表来表达存储结构,可表达结点之间的逻辑关系。

其结点里面需要有左右结点和存放的数据。

template <typename DataType>
struct Node{
    DataType data;
    Node<DataType> *lchild,*rchild;
}; 

如图所示:

二叉树链表的遍历

二叉树的操作需要采用递归函数实现,对于遍历方式,一般有四种方法:

二叉树的遍历是指从根结点出发,按照某种次序访问①二叉树中的所有结点,使得每个结点被访问一次且仅被访问一次。二叉树由根结点(D),根结点的左子树(L)和根结点的右子树(R)三部分组成。 这三部分共有六种全排列,分别是DLR,LDR,LRD、DRL、RDL和RLD,不失一般性,约定先左子树后右子树,则有前序(根)遍历、中序(根)遍历和后序(根)遍历。如果按二又树的层序依次访问各结点,可得到另一种遍历次序:层序遍历。

前序遍历二叉树的操作定义为:若二叉树为空,则空操作返回:否则执行下述操作。 ①访间根结点; ②前序遍历根结点的左子树; ③前序遍历根结点的右子树。

template <typename DataType>
void BiTree<DataType>::PreOrder(BiNode<DataType>*bt){
    if(bt==NULL){
        return;
    }else{
        cout<<bt->data<<"\t";
        PreOrder(bt->lchild);
        PreOrder(bt->rchild);
    }
}

中序遍历二叉树的操作定义为:若二叉树为空,则空操作返回:否则执行下述操作。 ①中序遍历根结点的左子树: ②访问根结点; ③中序遍历根结点的右子树。

template <typename DataType>
void BiTree<DataType>::InOrder(BiNode<DataType>*bt){
    if(bt==NULL){
        return;
    }else{
        InOrder(bt->lchild);
        cout<<bt->data<<"\t";
        InOrder(bt->rchild);
    }
}

后序遍历二叉树的操作定义为:若二叉树为空,则空操作返回:否则执行下述操作。 ①后序遍历根结点的左子树: ②后序遍历根结点的右子树: ③访问根结点。

template <typename DataType>
void BiTree<DataType>::PosOrder(BiNode<DataType>*bt){
    if(bt==NULL){
        return;
    }else{
        PosOrder(bt->lchild);
        PosOrder(bt->rchild);
        cout<<bt->data<<"\t";
    }
}

层序遍历二叉树的操作定义为:从二叉树的根结点开始,从上至下逐层遍历,同一层 按从左到右的顺序对结点逐个访问。

template <typename DataType>
void BiTree<DataType>::LevelOrder(){
    Node<DataType>*Q[1000],*q = NULL;
    int front = -1,rear = -1;
    if(root = NULL){
        return;
    }
    Q[++rear] = root;
    while(front != rear){
        q = Q[++front];
        cout<<q->data<<"\t";
        if(q->lchild != NULL){
            Q[++rear] = q->lchild;
        }
        if(q->rchild != NULL){
            Q[++rear] = q->rchild;
        }
    }
}

二叉树的构建与销毁

构造函数

本方法是通过根据一个结点序列来建立二叉树。需要把虚节点设置一个特定的值,比如用‘#’。

template <typename DataType>
Node<DataType> *BiTree<DataType>::Creat(){
    Node<DataType> *bt;
    char ch;
    cin>>ch;
    if(ch == '#'){
        bt = NULL;
    } else{
        bt = new Node<DataType>;
        bt->data = ch;
        bt->lchild = Creat();
        bt->rchild = Creat(); 
    }
    return bt;
}

析构函数

template <typename DataType>
void BiTree<DataType>::Release(Node<DataType> *bt){
    if(bt = NULL){
        return;
    }else{
        Release(bt->lchild);
        Release(bt->rchild);
        delete bt;
    }
}

二叉树的使用

#include<iostream> 
using namespace std;
​
struct BiNode
{
char data;
BiNode *lchild, *rchild;
};
​
​
class BiTree
{
public:
BiTree( ){root = Creat(root);} //构造函数,建立一棵二叉树
~BiTree( ){Release(root);} //析构函数,释放各结点的存储空间
void PreOrder( ){PreOrder(root);} //前序遍历二叉树
void InOrder( ){InOrder(root);} //中序遍历二叉树
void PostOrder( ){PostOrder(root);} //后序遍历二叉树
void LeverOrder( ); //层序遍历二叉树
private:
BiNode *Creat(BiNode *bt); //构造函数调用
void Release(BiNode *bt); //析构函数调用
void PreOrder(BiNode *bt); //前序遍历函数调用
void InOrder(BiNode *bt); //中序遍历函数调用
void PostOrder(BiNode *bt); //后序遍历函数调用
​
BiNode *root; //指向根结点的头指针
};
​
​
void BiTree :: PreOrder(BiNode *bt)
{
if (bt == NULL) return; //递归调用的结束条件
else {
cout << bt->data; //访问根结点bt的数据域
PreOrder(bt->lchild); //前序递归遍历bt的左子树
PreOrder(bt->rchild); //前序递归遍历bt的右子树
}
}
​
​
void BiTree :: InOrder(BiNode *bt)
{
if (bt == NULL) return; //递归调用的结束条件
else {
InOrder(bt->lchild); //前序递归遍历bt的左子树
cout << bt->data; //访问根结点bt的数据域
InOrder(bt->rchild); //前序递归遍历bt的右子树
}
}
​
​
void BiTree :: PostOrder(BiNode *bt)
{
if (bt == NULL) return; //递归调用的结束条件
else {
PostOrder(bt->lchild); //前序递归遍历bt的左子树
PostOrder(bt->rchild); //前序递归遍历bt的右子树
cout << bt->data; //访问根结点bt的数据域
}
}
​
​
void BiTree :: LeverOrder( )
{
BiNode *Q[100], *q = NULL; //顺序队列最多100个结点
int front = -1, rear = -1; //队列初始化
if (root == NULL) return; //二叉树为空,算法结束
Q[++rear] = root; //根指针入队
while (front != rear) //当队列非空时
{
q = Q[++front]; //出队
cout << q->data;
if (q->lchild != NULL) Q[++rear] = q->lchild;
if (q->rchild != NULL) Q[++rear] = q->rchild;
}
}
​
​
BiNode *BiTree :: Creat(BiNode *bt)
{
char ch;
cout << "请输入扩展二叉树的前序遍历序列,每次输入一个字符:";
cin >> ch; //输入结点的数据信息,假设为字符
if (ch == '#') bt = NULL; //建立一棵空树
else {
bt = new BiNode; bt->data = ch;
bt->lchild = Creat(bt->lchild); //递归建立左子树
bt->rchild = Creat(bt->rchild); //递归建立右子树
}
return bt;
}
​
​
void BiTree :: Release(BiNode *bt)
{
if (bt == NULL) return;
else{
Release(bt->lchild); //释放左子树
Release(bt->rchild); //释放右子树
delete bt; //释放根结点
}
}
​
int main( )
{
BiTree T; //定义对象变量T
cout << "该二叉树的前序遍历序列是:";
T.PreOrder( );
cout << "\n该二叉树的中序遍历序列是:";
T.InOrder( );
cout << "\n该二叉树的后序遍历序列是:";
T.PostOrder( );
cout << "\n该二叉树的层序遍历序列是:";
T.LeverOrder( );
return 0;
}

代码运行如下:

本次介绍就结束了,这次我介绍的结点使用的有两个指针,如果再加入一个,用来存储双亲结点,形成三叉链表。这样有利于寻找双亲结点。如这次分享对你有些收获,也给我一个赞支持与鼓励。

如你还想继续学下去,你可以看这篇,我在网上总结的知识点,可能有点长:

树的知识点总结https://blog.csdn.net/m0_67500944/article/details/126973302

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二叉树是一种常见的数据结构遍历二叉树有多种方法,包括先序遍历、中序遍历和后序遍历。以下是在C语言中用数组表示二叉树并进行遍历的示例代码: ```c #include <stdio.h> // 定义二叉树节点结构 struct TreeNode { int data; struct TreeNode *left; struct TreeNode *right; }; // 构建二叉树 struct TreeNode nodes[10]; // 使用数组表示二叉树 void buildTree() { for (int i = 0; i < 10; i++) { nodes[i].data = i; nodes[i].left = NULL; nodes[i].right = NULL; } nodes[0].left = &nodes[1]; nodes[0].right = &nodes[2]; nodes[1].left = &nodes[3]; nodes[1].right = &nodes[4]; nodes[2].left = &nodes[5]; nodes[2].right = &nodes[6]; } // 先序遍历 void preOrder(struct TreeNode *root) { if (root != NULL) { printf("%d ", root->data); preOrder(root->left); preOrder(root->right); } } // 中序遍历 void inOrder(struct TreeNode *root) { if (root != NULL) { inOrder(root->left); printf("%d ", root->data); inOrder(root->right); } } // 后序遍历 void postOrder(struct TreeNode *root) { if (root != NULL) { postOrder(root->left); postOrder(root->right); printf("%d ", root->data); } } int main() { buildTree(); printf("先序遍历结果:"); preOrder(&nodes[0]); printf("\n中序遍历结果:"); inOrder(&nodes[0]); printf("\n后序遍历结果:"); postOrder(&nodes[0]); return 0; } ``` 以上代码定义了一个二叉树的结构,使用数组表示节点,并实现了先序、中序和后序遍历的方法。在主函数中构建了一个二叉树,并进行了遍历操作,打印出遍历的结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值