C# 数组集合<四> 二元查找树(非递归遍历)

本文介绍了C#中二元查找树的非递归遍历方法,包括先根遍历、中序遍历和后根遍历。详细阐述了每个遍历的关键点,如先根遍历时右子节点先入栈,中序遍历通过双栈交替进行,以及后根遍历利用栈的特性实现节点的正确输出顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

非递归遍历:

先根遍历

public void StackPreOrder(Node head)
        {
            Console.WriteLine("Pre-Order:  ");
            if (head !=null)
            {
                Stack<Node> stack = new Stack<Node>();
                stack.Push(head);
                while (stack.Count>0)
                {
                    head = stack.Pop();
                    Console.WriteLine(head.Data+" ");
                    //压入栈顶  先进后出   (大的先进)
                    if (head.Right!=null)
                    {
                        stack.Push(head.Right);
                    }
                    if (head.Left !=null)
                    {
                        stack.Push(head.Left);
                    }
                }
            }
        }

关键点:
1.栈顶先插入Root节点,随即将其Pop()。
2.大的先进,二元查找树右边最大,所以 Right先进栈,Left后进。
3.循环开始先置换Head节点,同时Pop栈顶元素。



中序遍历

 public void StackInOrder(Node head)
        {
            Console.WriteLine("In-Order:  ");
            if (head != null)
            {
                Stack<Node> stack = new Stack<Node>();
                while (stack.Count > 0 || head != null)
                {
                    //先进后出     (从左往右 从小到大)

                    if (head != null)
                    {
                        stack.Push(head);
                        head = head.Left;
                    }
                    else
                    {
                        head = stack.Pop();
                        Console.WriteLine(head.Data + " ");
                        head = head.Right;
                    }
                }
            }
        }


关键点:
1.每次操作前head指向当前操作节点。
2.head不为空,进栈。
3.直至索引到左子树为null,head==null,Pop()栈顶,head置为当前节点右子树,继续循环判定head。
*head不为空进栈,置换为下一左子树。继续循环判定。
*head为空出栈,置换为下一右子树。继续循环判定。

后根遍历

双栈遍历


public void DoubleStackPostOrder(Node head)
        {
            Console.WriteLine("POST-Order:  ");
            if (head != null)
            {
                //双栈实现  非迭代遍历   排序栈   输出栈
                  Stack<Node> orderStack = new Stack<Node>();
                  Stack<Node> outputStack = new Stack<Node>();
                  orderStack.Push(head);
                while (orderStack.Count>0)
                {
                    head = orderStack.Pop();
                    outputStack.Push(head);
                    if (head.Left !=null)
                    {
                        orderStack.Push(head.Left);
                    }
                    if(head.Right !=null)
                    {
                        orderStack.Push(head.Right);
                    }
                }
                while (outputStack.Count > 0)
                {
                    Console.WriteLine(outputStack.Pop().Data + " ");
                }


            }
        }


关键点:
1.输出栈的特点:根节点永远最先进栈,因为先进后出,正好符合后根遍历的特点。
2.排序栈的特点:根节点且右子树永远最后进栈,每一轮挑出最大的给输出栈。后进先出符合此条件。
3.每一轮循环操作的head结点,就是将要进输出栈的成员。也是排序栈最大的。
*以此循环,直到最小的节点进入输出栈,循环结束输出。

单栈遍历

 public void SingleStackPostOrder(Node head)
        {
            Console.WriteLine("PSOT-Order : ");
            if (head != null)
            {
                Stack<Node> stack = new Stack<Node>();
                stack.Push(head);
                Node current = null;
                while  (stack.Count>0)
                {
                    //Peek 和 Pop 前者不改变栈的值,后者会Delete栈顶元素
                    current = stack.Peek();
                    if (current.Left != null&& head !=current.Left&&head !=current.Right)
                    {
                        stack.Push(current.Left);
                    }
                    else if (current.Right != null && head != current.Right)
                    {
                        stack.Push(current.Right);
                    }
                    else
                    {
                        Console.WriteLine(stack.Pop().Data + " ");
                        head = current;
                    }
                }
            }
        }



关键点:
1.head在未进行Pop操作前就是Root节点。Pop操作后,记录出栈的栈顶元素。
2.再循环取这次循环的栈顶Current,而head是上一次循环的栈顶。
3.判定   左节点进栈  那么(左节点不为空,且head不为当前操作节点的子节点)
4.判定   右节点进栈 那么 (右节点不为空,且head不为当前节点的右节点。同父级节点下的左子节点比右子节点先进去先Pop,所以head有可能为左节点)
3 4两个判定:遵循左右根输出。层次递进,索引最深,左进   左出   右进  右出   根出(直至Root).......


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值