热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

剑指Offer面试题:22.二叉搜索树的后序遍历序列

一、题目:二叉搜索树的后序遍历序列题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。例如在下面
一、题目:二叉搜索树的后序遍历序列

题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。

  例如在下面的一颗二叉搜索树中,输入数组{5,7,6,9,11,10,8},则返回true,因为这个整数序列是下图二叉搜索树的后序遍历结果。如果输入的数组是{7,4,6,5},由于没有哪棵二叉搜索树的后序遍历的结果是这个序列,因此返回false。

二、解题思路

2.1 核心步骤

  在后序遍历得到的序列中,最后一个数字是树的根结点的值。数组中前面的数字可以分为两部分:第一部分是左子树结点的值,它们都比根结点的值小;第二部分是右子树结点的值,它们都比根结点的值大

  因此,我们可以总结出算法步骤:

  Step1.通过取出序列最后一个元素得到二叉搜索树的根节点;

  Step2.在二叉搜索树中左子树的结点小于根结点,因此可以遍历一次得到左子树;

  Step3.在二叉搜索树中右子树的结点大于根结点,因此可以继续遍历后序元素得到右子树;

  Step4.重复以上步骤递归判断左右子树是不是二叉搜索树,如果都是,则返回true,如果不是,则返回false;

2.2 代码实现

    public static bool VerifySquenceOfBST(int[] sequence, int length)
{
if (sequence == null || length <= 0)
{
return false;
}

int root = sequence[length - 1];

int i = 0;
// 在二叉搜索树中左子树的结点小于根结点
for (; i 1; i++)
{
if (sequence[i] > root)
{
break;
}
}
// 在二叉搜索树中右子树的结点大于根结点
int j = i;
for (; j 1; j++)
{
if (sequence[j] < root)
{
// 如果找到小于根节点直接返回false
return false;
}
}
// 判断左子树是不是二叉搜索树
bool leftIsBST = true;
if (i > 0)
{
leftIsBST
= VerifySquenceOfBST(sequence, i);
}
// 判断右子树是不是二叉搜索树
bool rightIsBST = true;
if (j 1)
{
// C#中无法直接操作指针,在C/C++可以直接传递sequence+i
int[] newSequence = sequence.Skip(i).ToArray();
rightIsBST
= VerifySquenceOfBST(newSequence, length - i - 1);
}

return leftIsBST && rightIsBST;
}
三、单元测试

3.1 测试用例

    //            10
// / \
// 6 14
// /\ /\
// 4 8 12 16
[TestMethod]
public void SequenceTest1()
{
int[] data = { 4, 8, 6, 12, 16, 14, 10 };
bool result = SequenceHelper.VerifySquenceOfBST(data, data.Length);
Assert.AreEqual(result,
true);
}

// 5
// / \
// 4 7
// /
// 6
[TestMethod]
public void SequenceTest2()
{
int[] data = { 4, 6, 7, 5 };
bool result = SequenceHelper.VerifySquenceOfBST(data, data.Length);
Assert.AreEqual(result,
true);
}

// 5
// /
// 4
// /
// 3
// /
// 2
// /
// 1
[TestMethod]
public void SequenceTest3()
{
int[] data = { 1, 2, 3, 4, 5 };
bool result = SequenceHelper.VerifySquenceOfBST(data, data.Length);
Assert.AreEqual(result,
true);
}

// 1
// \
// 2
// \
// 3
// \
// 4
// \
// 5
[TestMethod]
public void SequenceTest4()
{
int[] data = { 5, 4, 3, 2, 1 };
bool result = SequenceHelper.VerifySquenceOfBST(data, data.Length);
Assert.AreEqual(result,
true);
}

// 树中只有1个结点
[TestMethod]
public void SequenceTest5()
{
int[] data = { 5 };
bool result = SequenceHelper.VerifySquenceOfBST(data, data.Length);
Assert.AreEqual(result,
true);
}

// 错误序列
[TestMethod]
public void SequenceTest6()
{
int[] data = { 7, 4, 6, 5 };
bool result = SequenceHelper.VerifySquenceOfBST(data, data.Length);
Assert.AreEqual(result,
false);
}

// 错误序列
[TestMethod]
public void SequenceTest7()
{
int[] data = { 4, 6, 12, 8, 16, 14, 10 };
bool result = SequenceHelper.VerifySquenceOfBST(data, data.Length);
Assert.AreEqual(result,
false);
}

// 错误序列
[TestMethod]
public void SequenceTest8()
{
bool result = SequenceHelper.VerifySquenceOfBST(null, 0);
Assert.AreEqual(result,
false);
}

3.2 测试结果

 

作者:周旭龙

出处:http://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。


推荐阅读
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 在金融和会计领域,准确无误地填写票据和结算凭证至关重要。这些文件不仅是支付结算和现金收付的重要依据,还直接关系到交易的安全性和准确性。本文介绍了一种使用C语言实现小写金额转换为大写金额的方法,确保数据的标准化和规范化。 ... [详细]
  • 360SRC安全应急响应:从漏洞提交到修复的全过程
    本文详细介绍了360SRC平台处理一起关键安全事件的过程,涵盖从漏洞提交、验证、排查到最终修复的各个环节。通过这一案例,展示了360在安全应急响应方面的专业能力和严谨态度。 ... [详细]
  • 本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 本文详细探讨了KMP算法中next数组的构建及其应用,重点分析了未改良和改良后的next数组在字符串匹配中的作用。通过具体实例和代码实现,帮助读者更好地理解KMP算法的核心原理。 ... [详细]
  • 深入解析Android自定义View面试题
    本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ... [详细]
  • 计算机网络复习:第五章 网络层控制平面
    本文探讨了网络层的控制平面,包括转发和路由选择的基本原理。转发在数据平面上实现,通过配置路由器中的转发表完成;而路由选择则在控制平面上进行,涉及路由器中路由表的配置与更新。此外,文章还介绍了ICMP协议、两种控制平面的实现方法、路由选择算法及其分类等内容。 ... [详细]
  • 本文详细介绍了如何解决Uploadify插件在Internet Explorer(IE)9和10版本中遇到的点击失效及JQuery运行时错误问题。通过修改相关JavaScript代码,确保上传功能在不同浏览器环境中的一致性和稳定性。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本文探讨了 C++ 中普通数组和标准库类型 vector 的初始化方法。普通数组具有固定长度,而 vector 是一种可扩展的容器,允许动态调整大小。文章详细介绍了不同初始化方式及其应用场景,并提供了代码示例以加深理解。 ... [详细]
author-avatar
宠医_臻爱一生_156
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有