二叉树的遍历

一、测试用图

在这里插入图片描述

二、代码示例

#include<iostream>
#include<vector>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<stdio.h>

typedef struct _Node {
	struct _Node* left;
	struct _Node* right;
	int member;
	_Node(int m)
	{
		this->left = NULL;
		this->right = NULL;
		this->member = m;
	}
}node,*Node;

Node create()
{	
	//创建一个二叉树用于测试
	Node root = new node(0);
	root->left = new node(1);
	root->right = new node(2);
	root->left->left = new node(3);
	root->left->right = new node(4);
	root->right->right = new node(5);
	root->left->left->left = new node(6);
	root->left->left->right = new node(7);
	root->right->right->left = new node(8);
	return root;
}

void pre_recurse(Node root)//递归先序遍历
{
	if(root)
	{
		std::cout << root->member << " ";//先访问根节点
		pre_recurse(root->left);//访问左子节点
		pre_recurse(root->right);//访问右子节点
	}
}

void pre_not_recurse(Node root)//非递归先序遍历
{
    std::stack<Node> s;
    if(root)
    {
        s.push(root);//将根节点入栈
    }
    while(!s.empty())//出栈访问结点,并将其左右子节点依次入栈[用于后续访问左右子树],实现访问顺序
    {
        Node tmp = s.top();
        s.pop();
        std::cout << tmp->member << " ";
        if(tmp->right)
        {
            s.push(tmp->right);
        }
        if(tmp->left)
        {
            s.push(tmp->left);
        }
    }
}

void mid_recurse(Node root)//递归中序遍历
{
	if (root)
	{
		mid_recurse(root->left);//先访问左节点
		std::cout << root->member << " ";//访问根节点
		mid_recurse(root->right);//访问右节点
	}
}

void mid_not_recurse(Node root)//非递归中序遍历
{
    Node node = root;
    std::stack<Node> s;
    while(node || !s.empty())
    {
        while(node)//将根节点及其第次左孩子入栈
        {
            s.push(node);
            node = node->left;
        }
        Node tmp = s.top();//出栈访问左子树节点或根节点,并将该节点右子树入栈
        std::cout << tmp->member << " ";
		s.pop();
        node = tmp->right;//局部左子树已全部入栈,所以出栈访问时只考虑入栈右子树,实现访问顺序
    }
}

void last_recurse(Node root)//递归后序遍历
{
	if (root)
	{
		last_recurse(root->left);//先访问左子节点
		last_recurse(root->right);//再访问右子节点
		std::cout << root->member << " ";//最后访问根节点
	}
}

void last_not_recurse(Node root)//非递归后序遍历
{
	Node p = root, flag = NULL;
	std::stack<Node> s;
	while(!s.empty() || p)
	{
		if(p)//入栈根节点及其第次左子节点
		{
			s.push(p);
			p = p->left;
		}
		else 
		{
			Node tmp = s.top();//取栈顶并查看右子树是否访问过
			if(tmp->right && tmp->right != flag)
			{//右子树未被访问,入栈右子树节点及其第次左子树
				p = tmp->right;
			}
			else
			{//无右子树或右子树已访问过,继续出栈访问剩余节点,实现访问顺序
				s.pop();
				std::cout << tmp->member << " ";
				flag = tmp;
				p = NULL;
			}
		}
	}
}

void layer(Node root)//层序遍历:访问顺序为当前层节点从左至右,并将下层节点存入可实现此顺序的结构
{//此处选用栈:即,将当前访问层节点入栈后,每次出栈访问节点后将其子节点通过先右后左的顺序入栈即刻,至栈空
	//时结束,实现访问顺序

//使用队列:出栈访问时的左右子节点入栈顺序不同而已。
	std::queue<Node> que;
	if (root)
	{
		que.push(root);
	}
	while (!que.empty())
	{
		Node tmp = que.front();
		std::cout << tmp->member << " ";
		if (tmp->left)
			que.push(tmp->left);
		if (tmp->right)
			que.push(tmp->right);
		que.pop();
	}
}


void push_child(std::stack<Node>& s, Node n, int type)
{
	if (1 == type)//先左后右
	{
		if (n->left)
			s.push(n->left);
		if (n->right)
			s.push(n->right);
	}
	if (2 == type)//先右后左
	{
		if (n->right)
			s.push(n->right);
		if (n->left)
			s.push(n->left);
	}
}

void s_scan(Node root)//'S'型遍历:将各层节点单独存储,并采用相反顺序的处理规则,实现访问顺序。
{
	std::stack<Node> s1, s2;
	int flag = 2;
	if (root)
	{
		std::cout << root->member << " ";
		push_child(s1, root, 1);
		while (!s1.empty() || !s2.empty())
		{
			if (1 == flag)
			{
				while (!s1.empty())
				{
					push_child(s2, s1.top(), 2);
					std::cout << s1.top()->member << " ";
					s1.pop();
				}
				flag = 2;
			}
			if (2 == flag)
			{
				while (!s2.empty())
				{
					push_child(s1, s2.top(), 1);
					std::cout << s2.top()->member << " ";
					s2.pop();
				}
				flag = 1;
			}
		}
	}
}

void kill(Node root)//释放树空间
{
	if (root)
	{
		if (root->left)
			kill(root->left);
		if (root->right)
			kill(root->right);
		delete root;
	}
}

int main()
{
	Node root = create();
    std::cout << " Pre order scan in recurse: " << std::endl;
	pre_recurse(root);
    std::cout << std::endl;
    std::cout << " Pre order without recurse: " << std::endl;
    pre_not_recurse(root);
    std::cout << std::endl;
    std::cout << std::endl;

    std::cout << " Mid order scan in recurse: " << std::endl;
	mid_recurse(root);
    std::cout << std::endl;
    std::cout << " Mid order whithout recurse: " << std::endl;
    mid_not_recurse(root);
	std::cout << std::endl;
    std::cout << std::endl;

    std::cout << " Last order in recurse: " << std::endl;
	last_recurse(root);
	std::cout << std::endl;
	std::cout << " Last order without recurse: " << std::endl;
	last_not_recurse(root);
	std::cout << std::endl;
    std::cout << std::endl;

    std::cout << " Layer scan: " << std::endl;
	layer(root);
	std::cout << std::endl;
	std::cout << std::endl;

    std::cout << " S route scan: " << std::endl;
	s_scan(root);
    std::cout << std::endl;
	std::cout << std::endl;

	kill(root);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值