二叉树

1.基本概念:

二叉树是每个结点最多有两个子结点的树,二叉树不是树的特殊形式,他们的数据结构是不一样的。

二叉树有以下性质:

1)第i-1层最多有2的i-1次方个结点

2)深度为k的二叉树最多有2的k次方-1个结点,可以由第一个性质推出

3)若0度的结点为n0个,2度的结点为n2个,则有n0=n2+1

2.二叉树的链式存储结构,二叉链表

public class node<T>

{

public T value{get;set;}//结点信息

public Node leftChild{get;set;}//左孩子

public Node rightChild{get;set;}//右孩子

}

3. 二叉树的遍历

前/先序遍历NLR:先访问结点的信息,然后遍历结点的左子树再遍历结点的右子树

中序遍历LNR:先遍历结点的左子树,然后访问结点的信息再遍历结点的右子树

后续遍历LRN:先遍历结点的左子树,然后遍历结点的右子树再访问结点的信息

4.遍历算法的实现

public class BinaryTree<T>
    {
        /// <summary>
        /// 前序遍历NLR N为结点信息,L为左子树R为右子树
        /// </summary>
        /// <param name="node"></param>
        public void PreOrderTraserval(Node<T> node)
        {
            if (node == null)
                return;
            Console.WriteLine(node.value);
            PreOrderTraserval(node.leftChild);
            PreOrderTraserval(node.rightChild);
        }
        /// <summary>
        /// 中序遍历
        /// </summary>
        /// <param name="node"></param>
        public void InOrderTraserval(Node<T> node)
        {
            if (node == null)
                return;
            InOrderTraserval(node.leftChild);
            Console.WriteLine(node.value);
            InOrderTraserval(node.rightChild);
        }
        /// <summary>
        /// 后序遍历
        /// </summary>
        /// <param name="node"></param>
        public void PostOrderTraserval(Node<T> node)
        {
            if (node == null)
                return;
            PostOrderTraserval(node.leftChild);
            PostOrderTraserval(node.rightChild);
            Console.WriteLine(node.value);
        }
    }


    public class Node<T>
    {
        public T value { get; set; }
        public Node<T> leftChild { get; set; }
        public Node<T> rightChild { get; set; }
    }

5.非递归实现

//前序遍历,非递归算法,需要恢复现场,所以需要用的栈,栈是一个后进先出的队列,先访问根结点后将根结点压入栈,将左结点压入栈直到为空,这时出栈(恢复现场),将结点的右子节点看做为跟压入栈中

public void PreOrder(Node node)

{

Stack<Node> s = new Stack<Node>();

while(node!=null || s.Count>0)//结点尚可能有子结点或者栈未空

{

if(node!=null)

{

Console.Write(node.value);

s.Push(node);

node = node.leftChild;

}

else

{

node = s.Pop();

node = node.rightChild;

}

}

}


//中序遍历和先序遍历代码上稍微改造即可,其的做法是先压入栈出栈时访问

public void InOrder(Node node)

{

Stack<Node> s = new Stack<Node>();

while(node!=null || s.Count>0)//结点尚可能有子结点或者栈未空

{

if(node!=null)

{

s.Push(node);

node = node.leftChild;

}

else

{

node = s.Pop();

Console.Write(node.value);

node = node.rightChild;

}

}

}


//后序遍历是三种遍历中最复杂的一个,基本流程差不多,出栈时访问,但是何时出栈是很有讲究的

public void PostOrder(Node node)

{

Stack<Node> s = new Stack<Node>();

Node pre =  null;


while(node!=null || s.Count>0)//结点尚可能有子结点或者栈未空

{

if(node!=null)

{

s.Push(node);

node = node.leftChild;

}

else

{

node = s.Peek();//拿到栈伟结点但不出栈

if( node.rightChild == null || pre==node.rightChild)//当右结点为空,或者右结点已经访问过了

{

s.Pop();//出栈

Console.Write(node.value);

pre = node;

node = null;

}

else

{

node = node.rightChild;

}

}

}

}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值