二叉搜索树JavaScript实现

* 什么是二叉搜索树?其形式就是二叉树,对于每个节点x,其左子树的值<=x.value,右子树的值>=x.value。

* 对于二叉搜索树,我们可以使用中序遍历,得到树上从小到大所有的元素。时间复杂度平均为O(n)。

function inorderTreeWalk(x) {
  if(x!== null) {
    inorderTreeWalk(x.left);
    print(x.key);
    inorderTreeWalk(x.right);
  }
}

* 当我们想要查询二叉搜索树中某个关键字应该怎么做呢?由于二叉搜索树左子树和右子树的特点,我们很容易写出:

function treeSearch(x,k) {  //最开始x代表根节点
  if(x === null || x.key === k) {
    return x;
  }
  if(k < x.key) {
    return treeSearch(x.left, k);
  } else {
    return treeSearch(x.right, k);
  }
}

我们还可以写出循环版本(一般比递归更高效):

function treeSearch(x, k) {
  while(x !== null || k !== x.key) {
    if(k < x.key) {
      x = x.left;
    } else {
      x = x.right;
    }
  }
  return x;
}

* 我们很容易可以找到二叉搜索树中的最小元素和最大元素,其查找时间复杂度为O(lgn):

function treeMinimum(x) {
  while(x.left !== null) {
    x = x.left;
  }
  return x;
}

function treeMaximum(x) {
  while(x.right !== null) {
    x = x.right;
  }
  return x;
}

* 有时候我们需要按中序遍历查找二叉搜索树某个节点的后继和前驱。分析二叉搜索树性质可知,如果该节点右子树不为空,则它的后继应该是右子树中的最小元素;若右子树为空,则该节点的后继应该是其双亲有左子树的父节点。前驱则与其对称.时间复杂度O(lgn):

function treeSuccessor(x) {  //后继查找
  if(x.right !== null) {
    return treeMinimum(x.right);
  } else {
    let y = x.parent;
    while(y !== null && x === y.right) {
      x = y;
      y = y.parent;
    }
    return y;
  }
}

function treeSuccessor(x) {  //前驱查找
  if(x.left !== null) {
    return treeMaximum(x.left);
  } else {
    let y = x.parent;
    while(y !== null && x === y.left) {
      x = y;
      y = y.parent;
    }
    return y;
  }
}

* 接下来我们还想要对二叉搜索树实现插入和删除操作。

  1、插入相对比较简单,我们只要遍历二叉树把值插入到合适的位置就行了。

function treeInsert(tree, newNode) {
  let y = null;
  while(tree !== null) {
    y = tree;
    if(newNode.key < tree.key) {
      tree = tree.left;
    } else {
      tree = tree.right;
    }
  }
  newNode.parent = y;
  if(y === null) {  // 树为空
    tree.root = newNode;
  } else {
    if(newNode.key < y.key) {
      y.left = newNode;
    } else {
      y.right = newNode;
    }
  }
}

  2、删除操作相对较复杂。假如删除z节点,我们考虑三种情况:z没有子节点、z有一个子节点、z有两个子节点。

    第一种情况:z没有子节点,则直接删除z,修改父节点属性,用null代替z。

    第二种情况:z只有一个子节点,则用子节点代替z。

    第三种情况:z有两个子节点,我们需要找到z的后继y,y肯定在z的右子树并且没有左孩子,当y恰好是z的右子节点,则直接用y替代z,并留下y的右孩子;否则先用y的右子节点替代y,再用y替代z。

function transplant(tree, u, v) {  //子树替换父节点方法
  if(u.p === null) {
    tree.root = v;
  } else if(u === u.parent.left) {
    u.parent.left = v;
  } else {
    u.parent.right = v;
  }
  if(v !== null) {
    v.parent = u.parent;
  }
}

function treeDelete(tree, z) {
  if(z.left === null) {
    transplant(tree, z, z.right);
  } else if(z.right === null) {
    transplant(tree, z, z.left);
  } else {
    let y = treeMinimum(z.right);
    if(y.parent !== z) {
      transplant(tree, y, y.right);
      y.right = z.right;
      y.right.parent = y;
    }
    transplant(tree, z, y);
    y.left = z.left;
    y.left.parent = y;
  }
}
时间: 2024-12-14 14:54:47

二叉搜索树JavaScript实现的相关文章

剑指offer:二叉搜索树与双向链表

1.题目描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 2.解题思路: (1)将左子树构造成双向链表,并返回链表头节点: (2)定位左子树双链表的尾节点: (3)如果左子树链表不为空,将当前root连缀其链尾: (4)将右子树构造出双向链表,并返回链表头节点: (5)如果右子树链表不为空,将当前root连缀其表头: (6)根据左子树链表是否为空,确定返回的节点. 3.JavaScript实现: function Conv

数据结构-二叉搜索树的js实现

一.树的相关概念 1.基本概念 子树 一个子树由一个节点和它的后代构成. 节点的度 节点所拥有的子树的个数. 树的度 树中各节点度的最大值 节点的深度 节点的深度等于祖先节点的数量 树的高度 树的高度等于所有节点深度的最大值 森林 若干课互不相交的树的集合.任何一棵树,删去根节点就变成了森林. 2. 二叉树 二叉树的定义 (1)二叉树中每个节点的度不大于2 (2)二叉树是有序的,其子树有左右之分,其次序不能随意颠倒 二叉树的性质 第k层上最多有2^(k-1)个节点 深度为k的二叉树最多有2^(k

用JS实现二叉搜索树

二叉树的节点最多只能有两个子节点,一个左侧子节点,一个右侧子节点. 二叉搜索树(BST),是二叉树的一种,但只允许在左侧节点存储比父节点小的值,在右侧节点存储比父节点大或等于父节点的值. 1.创建BST 1.1创建BST类 首先申明BST类的基本结构 function BinarySearchTree() { var Node = function(key){ this.key = key; this.left = null; this.right = null; }; var root = n

538. Convert BST to Greater Tree 二叉搜索树转换为更大树

Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus sum of all keys greater than the original key in BST. Example: Input: The root of a Binary Search Tree like thi

二叉搜索树

#include<stdio.h> #include<iostream> #include<math.h> #include<stdlib.h> using namespace std; struct TreeNode { TreeNode* p; TreeNode* l; TreeNode* r; int key; TreeNode() { p = 0; l = 0; r = 0; key = -1; } }; const int RANDMOD = 30

04-树4 是否同一棵二叉搜索树

给定一个插入序列就可以唯一确定一棵二叉搜索树.然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到.例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果.于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树. 输入格式: 输入包含若干组测试数据.每组数据的第1行给出两个正整数N (≤10)和L,分别是每个序列插入元素的个数和需要检查的序列个数.第2行给出N个以空格分隔的正整数,作为初始插入序列.最后L行,每行给出N个插入的元素,属于

二叉搜索树建立、插入、删除、前继节点、后继节点之c++实现

一.前言 一直以来,都对树有关的东西望而却步.以前每次说要看一看,都因为惰性,时间就那么荒废掉了.今天下个决心,决定好好的数据结构中的东西看一下.不知道看这篇文章的你,是不是和我有同样的感受,空有一颗努力的心,却迟迟没有付出行动.如果是的话,如果也想好好的把树的知识巩固一下的话,就让我们一起好好儿地把知识点过一遍吧.本文争取让看完的每一个没有基础的同学,都能有所收获.在正文开始前,先给自己加个油.加油(^ω^) 二.二叉搜索树的定义 二叉搜索树是指,对于某一个节点而言,它左边的节点都小于或等于它

数据结构——二叉搜索树、B树、B-树

数据结构——二叉搜索树.B树.B-树 1. 综述 二叉排序树(Binary Sort Tree),又叫二叉查找树(Binary Search Tree),也叫二叉排序树. 二叉搜索树满足以下性质: 1. 若根节点左子树不为空,则左子树上的所有节点均小于根节点: 2. 若根节点右子树不为空,则右子树上的所有节点均大于根节点: 3. 其左右子树也是二叉搜索树(递归定义): 4. 没有键值相等的点. B树就是B-树.B树/B-树英文叫B-Tree,可能被不小心翻译成了B-树.

PAT天梯赛练习题 L3-010. 是否完全二叉搜索树(完全二叉树的判断)

L3-010. 是否完全二叉搜索树 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 将一系列给定数字顺序插入一个初始为空的二叉搜索树(定义为左子树键值大,右子树键值小),你需要判断最后的树是否一棵完全二叉树,并且给出其层序遍历的结果. 输入格式: 输入第一行给出一个不超过20的正整数N:第二行给出N个互不相同的正整数,其间以空格分隔. 输出格式: 将输入的N个正整数顺序插入一个初始为空的二叉搜索树.在第一行中输出结果树的层序