博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据结构与算法:二叉树算法
阅读量:6503 次
发布时间:2019-06-24

本文共 5578 字,大约阅读时间需要 18 分钟。

内容衔接上一章

内容提要

  • 什么是树

  - 为什么使用树

  • 二叉树
  • 二叉查找树
  • 红黑树
  • B、B+树
  • 伸展树

可以点击链接感受下笔者用d3.js画的tree

是计算机科学中经常用到的一种数据结构。

  • 树是一种非线性的数据结构,以分层的方式存储数据。
  • 树被用来存储具有层级关系的数据,比如文件系统中的文件
  • 数还被用来存储有序列表

选择树而不是那些基本的数据结构,是因为:

  • 二叉树上进行查找特别快(而在链表上查找每次基本就是遍历,查找速度很慢)
  • 二叉树添加或删除元素也很快(而对数组执行添加或删除操作则不是这样)

树的遍历

树的遍历是树的一种重要的运算。所谓遍历是指对树中所有结点的信息的访问,即依次对树中每个结点访问一次且仅访问一次。树的3种最重要的遍历方式分别称为前序遍历、中序遍历和后序遍历。以这3种方式遍历一棵树时,若按访问结点的先后次序将结点排列起来,就可分别得到树中所有结点的前序列表、中序列表和后序列表。相应的结点次序分别称为结点的前序、中序和后序。

二叉树

这里我们将研究一种特殊的树:二叉树(二叉树,本质上,是对链表和数组的一个折中。)

图片描述

如上图,树是由一组以边连接的节点组成。

二叉树是一种特殊的树,它的子节点个数不超过两个

通过将子节点的个数限定为2,可以写出高效的程序在树中插入、查找和删除数据。

根节点:二叉树中最高那个节点没有父节点。

叶子节点: 最低下一层没有孩子节点的节点
剩下的节点被成为中间节点

二叉查找树(排序二叉树)Binary Search Tree

BST(Binary Search Tree)目的是为了提高查找的性能,其查找在平均和最坏的情况下都是logn级别,接近二分查找。

图片描述

如上图,相对较小的值保存在左节点中,较大的值保存在右节点中。这样能够使查找效率变高。

  • 所有非叶子结点至多拥有两个儿子(Left和Right);
  • 所有结点存储一个关键字;
  • 非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树;

有三种遍历BST的方式:

  • 中序遍历 (in-order)按照节点上的键值,以升序访问BST上的所有节点
  • 先序遍历 (pre-order)先访问根节点,然后以同样方式访问左子树和右子树
  • 后序遍历 (post-order)先访问叶子节点,从左子树到右子树,再到根节点
  • 层次遍历:只需按层次遍历即可
function BinaryTree() {            //二叉查找树由节点组成,所以我们先定义Node            //Node            var Node = function(data,left,right) {                this.data = data;                this.left = left;                this.right = right;               // this.show = show;            };                                    // var show = function() {            //         return = this.data;            // };                        var root = null;//设置根节点                          //insert()方法,用来向树中加入新节点            this.insert = function(data) {                var newNode = new Node(data,null,null);                if(root ===null){                    root = newNode;                }                else {                    insertNode(root,newNode);                    }            };            var insertNode = function(node,newNode) {                     if(newNode.data < node.data){                        if(node.left === null){                          node.left = newNode;                        }else{                          insertNode(node.left,newNode);                        }                     }else{                       if(node.right === null){                         node.right = newNode;                       }else{                         insertNode(node.right,newNode);                       }                     }                            };                                }        var nodes = [8,3,10,1,6,14,4,7,13];        var binaryTree = new BinaryTree();        nodes.forEach(function(data) {            binaryTree.insert(data);        });          //中序遍历     //先序遍历     //后序遍历

中序遍历

function BinaryTree() {            //二叉查找树由节点组成,所以我们先定义Node            //Node            var Node = function(data,left,right) {                this.data = data;                this.left = left;                this.right = right;               // this.show = show;            };                                    // var show = function() {            //         return = this.data;            // };                        var root = null;//设置根节点                          //insert()方法,用来向树中加入新节点            this.insert = function(data) {                var newNode = new Node(data,null,null);                if(root ===null){                    root = newNode;                }                else {                    insertNode(root,newNode);                    }            };            this.inOrderTraverse = function(callback) {                inOrderTraverseNode(root,callback);            }            var insertNode = function(node,newNode) {                     if(newNode.data < node.data){                        if(node.left === null){                          node.left = newNode;                        }else{                          insertNode(node.left,newNode);                        }                     }else{                       if(node.right === null){                         node.right = newNode;                       }else{                         insertNode(node.right,newNode);                       }                     }                            };            var inOrderTraverseNode = function(node,callback) {                if (node!==null) {                    inOrderTraverseNode(node.left,callback);                    callback(node.data);                    inOrderTraverseNode(node.right,callback);                }            }                                }        var nodes = [8,3,10,1,6,14,4,7,13];        var binaryTree = new BinaryTree();        nodes.forEach(function(data) {            binaryTree.insert(data);        });          //中序遍历      var callback = function(data) {          console.log(data);      }      binaryTree.inOrderTraverse(callback);

图片描述

前序遍历(pre-order)

我们看到中序遍历可以把二叉树的节点按照从小到大的顺序打印出来;

前序遍历可以在我们已经拥有一颗二叉树的时候,高效的复制这颗二叉树。
通过其前序遍历去复制一颗二叉树比重新构造一颗二叉树要高效得多

前(先)序遍历:按照最优先顺序沿一定路径经过路径上所有的站。在二叉树中,先根后左再右。巧记:根左右。

图片描述

clipboard.png

后序遍历

红黑树

红黑树: 处于平衡状态的特殊二叉查找树

图片描述

B树、B+树

维基百科对B树的定义为“在计算机科学中,B树(B-tree)是一种树状数据结构,它能够存储数据、对其进行排序并允许以O(log n)的时间复杂度运行进行查找、顺序读取、插入和删除的数据结构。B树,概括来说是一个节点可以拥有多于2个子节点的二叉查找树。与自平衡二叉查找树不同,B-树为系统最优化大块数据的读和写操作。B-tree算法减少定位记录时所经历的中间过程,从而加快存取速度。普遍运用在数据库和文件系统。

高级数据(树、堆、图)应该平时多积累,好好理解,比如理解了堆是什么样的数据结构,在面试中遇见的「查找最大的 K 个数」这类算法问题,就会迎刃而解。

伸展树

常见面试题

1、已知一颗二叉树,如果先序遍历的节点顺序是:ADCEFGHB, 中序遍历是:CDFEGHAB,则后序遍历结果是()
A. CFHGEBDA
B. CDFEGHBA
C. FGHCDEBA
D. CFHGEDBA

解答:

对于二叉树的遍历方式一般分为三种先序、中序、后序三种方式:

先序遍历(根左右)

若二叉树为空,则不进行任何操作:否则
1、访问根结点。
2、先序方式遍历左子树。
3、先序遍历右子树。

中序遍历 (左根右)

若二叉树为空,则不进行任何操作:否则
1、中序遍历左子树。
2、访问根结点。
3、中序遍历右子树。

后序遍历 (左右根)

若二叉树为空,则不进行任何操作:否则
1、后序遍历左子树。
2、后序遍历右子树。
3、放问根结点。

因此,根据题目给出的先序遍历和中序遍历,可以画出二叉树: 

图片描述
选 4

参考

《数据结构与算法Javascript描述》

转载地址:http://hdqyo.baihongyu.com/

你可能感兴趣的文章
基于阿里雲Oracle12cR2(Linux)實例靜默安装Cloud Control 13c 13.3
查看>>
硬科技产业的创新与难点,核心都在“技术落地”
查看>>
通过DataWorks数据集成归档日志服务数据至MaxCompute进行离线分析
查看>>
「镁客·请讲」翼辉信息黄晓清:国产系统需有自己的灵魂,一行一行去码并不可怕...
查看>>
【软件】Eclipse 下载
查看>>
阿里云全球19个地域节点,哪个节点的服务器好,速度快?
查看>>
PostgreSQL 9.6 for Centos7.4 最佳实践安装
查看>>
java B2B2C Springcloud电子商务平台源码 -Feign之源码解析
查看>>
Unity C#编程优化——枚举
查看>>
熊先生做原型之:简单、粗暴、有效
查看>>
TensorFlow系列专题(三):深度学习简介
查看>>
Unity Excel转Json小工具excel2json
查看>>
(十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
查看>>
切割Nginx日志的脚本
查看>>
19.7 主动模式和被动模式;19.8 添加监控主机;19.9 添加自定义模板;19.10 处理图形中的乱码;19.11...
查看>>
解决FTP服务器命令好使,工具不好使。
查看>>
awk工具(三剑客)
查看>>
Log4j 2 + Slf4j 的配置和使用Apache
查看>>
一次arp防护配置错误导致的故障
查看>>
apt-get install 报错解决办法: Unmet dependencies. Try 'apt-get -f install' with no packages
查看>>