二叉树遍历(前序、中序、后序、层次、深度优先、广度优先遍历)

二叉树是一种非常重要的数据结构,非常多其他数据结构都是基于二叉树的基础演变而来的。对于二叉树,有深度遍历和广度遍历,深度遍历有前序、中序以及后序三种遍历方法,广度遍历即我们寻常所说的层次遍历。由于树的定义本身就是递归定义,因此採用递归的方法去实现树的三种遍历不仅easy理解并且代码非常简洁,而对于广度遍历来说,须要其他数据结构的支撑。比方队列。所以。对于一段代码来说,可读性有时候要比代码本身的效率要重要的多。

四种基本的遍历思想为:

前序遍历:根结点 ---> 左子树 ---> 右子树

中序遍历:左子树---> 根结点 ---> 右子树

后序遍历:左子树 ---> 右子树 ---> 根结点

层次遍历:仅仅需按层次遍历就可以

比如,求以下二叉树的各种遍历

前序遍历:1  2  4  5  7  8  3  6 

中序遍历:4  2  7  5  8  1  3  6

后序遍历:4  7  8  5  2  6  3  1

层次遍历:1  2  3  4  5  6  7  8

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 树
{
    class Node
    {
        //成员变量
        private object _data;       //数据
        private Node _left;     //左孩子
        private Node _right;       //右孩子
        public object Data {
            get {
                return _data;
            }
        }
        public Node Left {
            set {
                _left = value;
            }
            get {
                return _left;
            }
        }
        public Node Right {
            set {
                _right = value;
            }
            get {
                return _right;
            }
        }
        public Node(object data) {
            this._data = data;
        }
        public override string ToString()
        {
            return _data.ToString();
        }
    }
}
using System;
using System.Collections.Generic; 

namespace 树
{
    class BinaryTree
    {
        private Node _head;     //头结点
        private string _cStr;       //构建二叉树的字符串

        public Node Head {
            get {
                return _head;
            }
        }
        //构造方法
        public BinaryTree(string constructStr) {
            _cStr = constructStr;       //保存构造字符串
            _head = new Node(_cStr[0]); //添加头结点
            Add(_head, 0);      //给头结点添加孩子节点
        }

        private void Add(Node parent, int index) {
            int leftIndex = 2 * index + 1;  //计算左孩子的索引
            int rightIndex = 2 * index + 2; //计算右孩子的索引
            if (leftIndex < _cStr.Length) {  //如果索引没有超过字符串的长度
                if(_cStr[leftIndex] != '#') { //# 表示空结点
                    parent.Left = new Node(_cStr[leftIndex]);
                    //递归调用Add方法添加左孩子的孩子节点
                    Add(parent.Left,leftIndex);
                }
            }
            if (rightIndex < _cStr.Length) {
                if (_cStr[rightIndex] != '#')
                {
                    parent.Right = new Node(_cStr[rightIndex]);
                    Add(parent.Right, rightIndex);
                }
            }
        }

        //先序遍历
        public void PreOrder(Node node) {
            if (node != null) {
                Console.Write(node.ToString());
                PreOrder(node.Left);    //递归左
                PreOrder(node.Right);   //递归右
            }
        }
        //中序遍历
        public void MidOrder(Node node) {
            if (node != null) {
                MidOrder(node.Left);
                Console.Write(node.ToString());
                MidOrder(node.Right);
            }
        }
        //后续遍历
        public void AfterOrder(Node node) {
            if (node != null) {
                AfterOrder(node.Left);
                AfterOrder(node.Right);
                Console.Write(node.ToString());
            }
        }
        //广度优先遍历
        public void LevelOrder() {
            Queue<Node> queue = new Queue<Node>();      //创建一个队列对象
            queue.Enqueue(_head);       //将根节点压入队列
            while (queue.Count > 0) {       //只要队列不为空
                Node node = queue.Dequeue();        //出队
                Console.Write(node.ToString());
                if (node.Left != null) {        //如果左孩子不为空
                    //将左孩子压入队列
                    queue.Enqueue(node.Left);
                }
                if (node.Right != null)//如果右孩子不为空
                {
                    //将右孩子压入队列
                    queue.Enqueue(node.Right);
                }
            }
        }
    }
}
using System; 
namespace 树
{
    class Program
    {
        static void Main(string[] args)
        {
            //string cStr = "ABCDE#F";
            string cStr = "12345678";
            BinaryTree bTree = new BinaryTree(cStr);//使用字符串构造二叉树
            Console.Write("先序遍历:");
            bTree.PreOrder(bTree.Head); //先序遍历
            Console.WriteLine();
            Console.Write("中序遍历:");
            bTree.MidOrder(bTree.Head); //中序遍历
            Console.WriteLine();
            Console.Write("后序遍历:");
            bTree.AfterOrder(bTree.Head); //后序遍历
            Console.WriteLine();

            Console.Write("广度优先遍历:");
            bTree.LevelOrder();
            Console.ReadKey();
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值