二叉树的四种遍历算法(结构体数组)

一、二叉树的定义

        以字符串的形式定义一棵二叉树的先序序列,若字符是‘#’,表示该二叉树是空树,否则该字符是相应结点的数据元素。

例:ABDG##HI####CE#J##F##

对应的二叉树:

 思路讲解:

        想要遍历二叉树,首先我们需要知道该二叉树是什么样子的,一般来说画出二叉树需要二叉树的先序序列+中序序列或者后序序列+中序序列,这里由于‘#’代表该二叉树是空树,让我们能够根据给出的先序序列画出二叉树。

        (1)我们知道二叉树的先序遍历是根左右的顺序,所以A为整个树的根结点,B为A的左子树。B后面是D,不是‘#’,说明B在该子树中为根结点,D为B的左子树,同理,G为D的左子树。此时的画出的树应该是这样的:

         (2)接下来,G后面是‘#’,说明G没有左子树,这时已经遍历了G(根结点)以及它的左子树,由根左右的顺序,然后是它的右子树,下一个是‘#’,说明G既没有左子树,也没有右子树,为叶子结点。

        (3)向上回溯,发现D没有遍历右子树,填入H即为D的右子树,H为该子树的根结点,填入I为H的左子树,I后面有两个‘#’,说明I为叶子结点。

        重复(1)(2)(3)步骤,直到画出二叉树。

二、创建二叉树

1.定义结构体数组

const int max=10000;
struct tree
{
    char ch;
    int lch;
    int rch;
}datas[max];//这里直接定义了一个结构体数组,等价于struct tree datas[max]

2.创建二叉树

#include<iostream>
using namespace std;

const int maxnum=1000;//在create_tree函数中需要用到的变量。
char ch;
int count=0;//为结点进行编号

struct tree
{
    char ch;
    int lch;
    int rch;
}datas[maxnum];

int create_tree(int num)
{
    cin>>ch;
    if(ch=='#')
    {
        num=0;
        return num;
    }
    else
    {
        count++;
        num=count;
        datas[num].ch=ch;
        datas[num].lch=0;//初始化结点的左右子树
        datas[num].rch=0;
        datas[num].lch=create_tree(num);
        datas[num].rch=create_tree(num);
    }
    return num;
}
int main()
{
    int root=create_tree(0);
    return 0;
}

三、遍历子树

1.先序遍历

        先序遍历遵循根左右的顺序。

void preorder(int a)
{
	if(!a)
	{
		return;
	}
	cout<<datas[a].ch;
	preorder(datas[a].lch);
	preorder(datas[a].rch);
}

2.中序遍历

        中序遍历遵循左根右的顺序。

void inorder(int a)
{
	if(!a)
	{
		return;
	}
	inorder(datas[a].lch);
	cout<<datas[a].ch;
	inorder(datas[a].rch);
}

3.后序遍历

        后序遍历遵循左右根的顺序。

void postorder(int a)
{
	if(!a)
	{
		return;
	}
	postorder(datas[a].lch);
	postorder(datas[a].rch);
	cout<<datas[a].ch;
}

4.层次遍历

        层次遍历可以使用队列结构(先进先出的特点)来完成算法。

        1.初始化一个队列,根结点入队。

        2.当队列非空时,循环执行下列步骤,否则遍历结束。

        3.出队一个结点,并访问该结点。

        4.若该结点的左子树非空,则左子树入队。

        5.若该结点的右子树非空,则右子树入队。

void level_order(int x)
{
	char t;
	int s;
	queue<int> p;
	if(x)//if运行条件为x不等于0 
	{
		p.push(x);
		while(!p.empty())
		{
			s=p.front();
			p.pop();
			t=datas[s].ch;
			cout<<t;
			if(datas[s].lch!=0)
			{
				p.push(datas[s].lch);
			}
			if(datas[s].rch!=0)
			{
				p.push(datas[s].rch);
			}
		}		
	}
}

 四、完整代码

#include<iostream>
#include<queue>
using namespace std;

const int maxnum=1000;
char ch;
int count=0;

struct tree
{
    char ch;
    int lch;
    int rch;
}datas[maxnum];

int create_tree(int num)
{
    cin>>ch;
    if(ch=='#')
    {
        num=0;
        return num;
    }
    else
    {
        count++;
        num=count;
        datas[num].ch=ch;
        datas[num].lch=0;
        datas[num].rch=0;
        datas[num].lch=create_tree(num);
        datas[num].rch=create_tree(num);
    }
    return num;
}

void preorder(int a)
{
	if(!a)
	{
		return;
	}
	cout<<datas[a].ch;
	preorder(datas[a].lch);
	preorder(datas[a].rch);
}

void inorder(int a)
{
	if(!a)
	{
		return;
	}
	inorder(datas[a].lch);
	cout<<datas[a].ch;
	inorder(datas[a].rch);
}

void postorder(int a)
{
	if(!a)
	{
		return;
	}
	postorder(datas[a].lch);
	postorder(datas[a].rch);
	cout<<datas[a].ch;
}

void level_order(int x)
{
	char t;
	int s;
	queue<int> p;
	if(x)//if运行条件为x不等于0 
	{
		p.push(x);
		while(!p.empty())
		{
			s=p.front();
			p.pop();
			t=datas[s].ch;
			cout<<t;
			if(datas[s].lch!=0)
			{
				p.push(datas[s].lch);
			}
			if(datas[s].rch!=0)
			{
				p.push(datas[s].rch);
			}
		}		
	}
}

int main()
{
    int root=create_tree(0);
    cout<<"二叉树的先序遍历序列:"<<endl;
    preorder(root);
    cout<<endl;
    cout<<"二叉树的中序遍历序列:"<<endl;
	inorder(root);
	cout<<endl;
	cout<<"二叉树的后序遍历序列:"<<endl;
	postorder(root);
	cout<<endl;
	cout<<"二叉树的层序遍历序列:"<<endl;
	level_order(root); 
    return 0;
}

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
二叉树遍历可以通过结构体数组存储实现,具体算法步骤如下: 1. 定义二叉树的结构体,包括节点值、左子节点和右子节点。 ``` struct TreeNode { int val; TreeNode* left; TreeNode* right; }; ``` 2. 定义结构体数组,用于存储二叉树节点的值。 ``` struct Node { int val; bool visited; }; ``` 其中,visited 表示该节点是已被访问过。 3. 创建二叉树,将结构体数组中的值存储到二叉树中。 ``` TreeNode* createTree(Node* nodes, int n, int i) { if (i >= n || nodes[i].val == -1) { return NULL; } TreeNode* root = new TreeNode(); root->val = nodes[i].val; root->left = createTree(nodes, n, 2 * i + 1); root->right = createTree(nodes, n, 2 * i + 2); return root; } ``` 其中,n 表示结构体数组的长度,i 表示当前节点在结构体数组中的位置。 4. 中序遍历二叉树,将遍历结果存储到另一个结构体数组中。 ``` void inOrder(TreeNode* root, Node* nodes, int& i) { if (!root) { return; } inOrder(root->left, nodes, i); nodes[i].val = root->val; nodes[i].visited = false; i++; inOrder(root->right, nodes, i); } ``` 其中,i 表示当前节点在结构体数组中的位置。 5. 实现遍历函数,通过结构体数组实现二叉树遍历。 ``` void traverse(Node* nodes, int n, TreeNode* root) { stack<TreeNode*> s; int i = 0; s.push(root); while (!s.empty()) { TreeNode* node = s.top(); s.pop(); if (!node) { continue; } if (!nodes[i].visited) { cout << node->val << " "; nodes[i].visited = true; } else { s.push(node->right); } s.push(node); s.push(node->left); i++; } } ``` 其中,使用栈实现二叉树遍历,节点访问的顺序与入栈的顺序相同,遍历过程中使用结构体数组记录每个节点是已被访问过。 通过结构体数组存储二叉树,可以方便地实现对二叉树遍历操作,并且可以避免指针操作带来的风险和复杂性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

琉璃蓝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值