成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript數(shù)據(jù)結(jié)構(gòu)與算法(九)二叉樹(shù)和二叉搜索樹(shù)

zhaofeihao / 3310人閱讀

摘要:二叉樹(shù)和二叉搜索樹(shù)二叉樹(shù)的節(jié)點(diǎn)最多只能有兩個(gè)節(jié)點(diǎn),而二叉搜索樹(shù)只允許在左側(cè)的節(jié)點(diǎn)處存儲(chǔ)比父節(jié)點(diǎn)小的值,在右側(cè)節(jié)點(diǎn)存儲(chǔ)比父節(jié)點(diǎn)大的值。接收回調(diào)函數(shù)作為參數(shù)先序遍歷先序遍歷是以優(yōu)先于后代節(jié)點(diǎn)的順序訪問(wèn)沒(méi)和節(jié)點(diǎn)的。

樹(shù)是一種非順序數(shù)據(jù)結(jié)構(gòu),對(duì)于存儲(chǔ)需要快速查找的數(shù)據(jù)非常有用。樹(shù)是一種分層數(shù)據(jù)的抽象模型,現(xiàn)實(shí)生活中最常見(jiàn)的例子就是家譜,或者是公司的組織架構(gòu)圖。

樹(shù) 樹(shù)的相關(guān)術(shù)語(yǔ)

樹(shù)中的每一個(gè)元素都是節(jié)點(diǎn),節(jié)點(diǎn)分為內(nèi)部節(jié)點(diǎn)和外部節(jié)點(diǎn)。其中:
至少有一個(gè)子節(jié)點(diǎn)的節(jié)點(diǎn)稱為內(nèi)部節(jié)點(diǎn)(例如圖中節(jié)點(diǎn)7,5,9,15,13,20),沒(méi)有子元素的節(jié)點(diǎn)為外部節(jié)點(diǎn)或葉節(jié)點(diǎn)(例如圖中節(jié)點(diǎn)3,6,8,10,12,14,18,25)。
位于樹(shù)頂部的節(jié)點(diǎn)叫做根節(jié)點(diǎn),它沒(méi)有父節(jié)點(diǎn)。
節(jié)點(diǎn)的一個(gè)屬性是深度,節(jié)點(diǎn)的深度 取決于它的祖先節(jié)點(diǎn)的數(shù)量。樹(shù)的高度取決于深度的最大值。同樣一棵樹(shù)也可以分為層級(jí),根節(jié)點(diǎn)在第0層,它的子節(jié)點(diǎn)在第1層,以此類推。

二叉樹(shù)和二叉搜索樹(shù)

二叉樹(shù)的節(jié)點(diǎn)最多只能有兩個(gè)節(jié)點(diǎn),而二叉搜索樹(shù)只允許在左側(cè)的節(jié)點(diǎn)處存儲(chǔ)(比父節(jié)點(diǎn))小的值,在右側(cè)節(jié)點(diǎn)存儲(chǔ)(比父節(jié)點(diǎn))大的值。

創(chuàng)建BinarySearchTree
const Compare = {
  LESS_THAN: -1,
  BIGGER_THAN: 1,
  EQUALS: 0
};
function defaultCompare(a, b) {
  if (a === b) {
    return Compare.EQUALS;
  }
  return a < b ? Compare.LESS_THAN : Compare.BIGGER_THAN;
};
class Node {
  constructor(key) {
    this.key = key;
    this.left = undefined;
    this.right = undefined;
  };
//下面我們會(huì)聲明BinarySearchTree類的基本骨架
class BinarySearchTree {
  constructor(compareFn = defaultCompare) {
    this.compareFn = compareFn;
    this.root = undefined;
  }
向二叉搜索樹(shù)插入一個(gè)鍵
insert(key) {
    // special case: first key
    if (this.root == null) {
      this.root = new Node(key);
    } else {
      this.insertNode(this.root, key);
    }
  }

  insertNode(node, key) {
    if (this.compareFn(key, node.key) === Compare.LESS_THAN) {
      if (node.left == null) {
        node.left = new Node(key);
      } else {
        this.insertNode(node.left, key);
      }
    } else if (node.right == null) {
      node.right = new Node(key);
    } else {
      this.insertNode(node.right, key);
    }
  }
樹(shù)的遍歷 中序遍歷

中序遍歷是一種以上行順序訪問(wèn)BST所有節(jié)點(diǎn)的遍歷方式,也就是從最小到最大的順序訪問(wèn)所有節(jié)點(diǎn)。中序遍歷的一種應(yīng)用是對(duì)樹(shù)進(jìn)行排序操作。

//inOrderTraverse接收回調(diào)函數(shù)作為參數(shù)
inOrderTraverse(callback) {
    this.inOrderTraverseNode(this.root, callback);
  }

  inOrderTraverseNode(node, callback) {
    if (node != null) {
      this.inOrderTraverseNode(node.left, callback);
      callback(node.key);
      this.inOrderTraverseNode(node.right, callback);
    }
  }
先序遍歷

先序遍歷是以優(yōu)先于后代節(jié)點(diǎn)的順序訪問(wèn)沒(méi)和節(jié)點(diǎn)的。先序遍歷的一種應(yīng)用是打印一個(gè)結(jié)構(gòu)化的文檔、我們來(lái)看代碼實(shí)現(xiàn)

preOrderTraverse(callback) {
    this.preOrderTraverseNode(this.root, callback);
  }

  preOrderTraverseNode(node, callback) {
    if (node != null) {
      callback(node.key);
      this.preOrderTraverseNode(node.left, callback);
      this.preOrderTraverseNode(node.right, callback);
    }
  }
后序遍歷

后序遍歷就是縣訪問(wèn)節(jié)點(diǎn)的后代節(jié)點(diǎn),在訪問(wèn)節(jié)點(diǎn)本身。后序遍歷的一種應(yīng)用是計(jì)算一個(gè)目錄及其子目錄中所有文件所占空間的大小

postOrderTraverse(callback) {
    this.postOrderTraverseNode(this.root, callback);
  }

  postOrderTraverseNode(node, callback) {
    if (node != null) {
      this.postOrderTraverseNode(node.left, callback);
      this.postOrderTraverseNode(node.right, callback);
      callback(node.key);
    }
  }
搜索樹(shù)中的值 搜索最小值
min() {
    return this.minNode(this.root);
  }

  minNode(node) {
    let current = node;
    while (current != null && current.left != null) {
      current = current.left;
    }
    return current;
  }
搜索最大值
max() {
    return this.maxNode(this.root);
  }

  maxNode(node) {
    let current = node;
    while (current != null && current.right != null) {
      current = current.right;
    }
    return current;
  }
搜索特定的值
search(key) {
    return this.searchNode(this.root, key);
  }

  searchNode(node, key) {
    if (node == null) {
      return false;
    }
    if (this.compareFn(key, node.key) === Compare.LESS_THAN) {
      return this.searchNode(node.left, key);
    } if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) {
      return this.searchNode(node.right, key);
    }
    return true;
  }
移除節(jié)點(diǎn)
removeNode(node, key) {
    if (node == null) {
      return undefined;
    }
    if (this.compareFn(key, node.key) === Compare.LESS_THAN) {
      node.left = this.removeNode(node.left, key);
      return node;
    } if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) {
      node.right = this.removeNode(node.right, key);
      return node;
    }
    // key is equal to node.item
    // handle 3 special conditions
    // 1 - a leaf node
    // 2 - a node with only 1 child
    // 3 - a node with 2 children
    // case 1 移除一個(gè)葉節(jié)點(diǎn)
    if (node.left == null && node.right == null) {
      node = undefined;
      return node;
    }
    // case 2 移除有一個(gè)左側(cè)或者右側(cè)子節(jié)點(diǎn)的節(jié)點(diǎn)
    if (node.left == null) {
      node = node.right;
      return node;
    } if (node.right == null) {
      node = node.left;
      return node;
    }
    // case 3    移除有兩個(gè)子節(jié)點(diǎn)的節(jié)點(diǎn)
    const aux = this.minNode(node.right);
    node.key = aux.key;
    node.right = this.removeNode(node.right, aux.key);
    return node;
  }
}

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/110039.html

相關(guān)文章

  • 一篇文章學(xué)會(huì)二叉樹(shù)和二叉查找樹(shù)

    摘要:二叉樹(shù)和二叉查找樹(shù)一個(gè)父節(jié)點(diǎn)的兩個(gè)子節(jié)點(diǎn)分別稱為左節(jié)點(diǎn)和右節(jié)點(diǎn)。下圖展示了一顆二叉樹(shù)當(dāng)考慮某種特殊的二叉樹(shù),比如二叉查找樹(shù)時(shí),確定子節(jié)點(diǎn)非常重要。實(shí)現(xiàn)二叉查找樹(shù)定義對(duì)象?,F(xiàn)在可以創(chuàng)建一個(gè)類來(lái)表示二叉查找樹(shù)。因此二叉查找樹(shù)也被叫做二叉排序樹(shù)。 樹(shù)是計(jì)算機(jī)科學(xué)中經(jīng)常用到的一種數(shù)據(jù)結(jié)構(gòu)。樹(shù)是一種非線性的數(shù)據(jù)結(jié)構(gòu),以分層的方式存儲(chǔ)數(shù)據(jù)。 樹(shù)被用來(lái)存儲(chǔ)具有層級(jí)關(guān)系的數(shù)據(jù),比如文件系統(tǒng)中的文件。 ...

    BaronZhang 評(píng)論0 收藏0
  • 每周一練 之 數(shù)據(jù)結(jié)構(gòu)算法(Tree)

    摘要:假設(shè)一個(gè)二叉搜索樹(shù)具有如下特征節(jié)點(diǎn)的左子樹(shù)只包含小于當(dāng)前節(jié)點(diǎn)的數(shù)。所有左子樹(shù)和右子樹(shù)自身必須也是二叉搜索樹(shù)。代碼實(shí)現(xiàn)二叉樹(shù)節(jié)點(diǎn)定義來(lái)源驗(yàn)證二叉搜索樹(shù)解析 showImg(https://segmentfault.com/img/remote/1460000019005270); 這是第六周的練習(xí)題,最近加班比較多,上周主要完成一篇 GraphQL入門教程 ,有興趣的小伙伴可以看下哈。 ...

    zhonghanwen 評(píng)論0 收藏0
  • 每周一練 之 數(shù)據(jù)結(jié)構(gòu)算法(Tree)

    摘要:假設(shè)一個(gè)二叉搜索樹(shù)具有如下特征節(jié)點(diǎn)的左子樹(shù)只包含小于當(dāng)前節(jié)點(diǎn)的數(shù)。所有左子樹(shù)和右子樹(shù)自身必須也是二叉搜索樹(shù)。代碼實(shí)現(xiàn)二叉樹(shù)節(jié)點(diǎn)定義來(lái)源驗(yàn)證二叉搜索樹(shù)解析這是第六周的練習(xí)題,最近加班比較多,上周主要完成一篇 GraphQL入門教程 ,有興趣的小伙伴可以看下哈。 下面是之前分享的鏈接: 1.每周一練 之 數(shù)據(jù)結(jié)構(gòu)與算法(Stack) 2.每周一練 之 數(shù)據(jù)結(jié)構(gòu)與算法(LinkedList) 3...

    fizz 評(píng)論0 收藏0
  • 學(xué)習(xí)javascript數(shù)據(jù)結(jié)構(gòu)(四)——樹(shù)

    摘要:原文博客地址學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)四樹(shù)知乎專欄簡(jiǎn)書專題前端進(jìn)擊者知乎前端進(jìn)擊者簡(jiǎn)書博主博客地址的個(gè)人博客人之所能,不能兼?zhèn)?,棄其所短,取其所長(zhǎng)。通常子樹(shù)被稱作左子樹(shù)和右子樹(shù)。敬請(qǐng)期待數(shù)據(jù)結(jié)構(gòu)篇最后一篇文章學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)五圖參考文章樹(shù)數(shù)據(jù)結(jié)構(gòu)二叉樹(shù) 前言 總括: 本文講解了數(shù)據(jù)結(jié)構(gòu)中的[樹(shù)]的概念,盡可能通俗易懂的解釋樹(shù)這種數(shù)據(jù)結(jié)構(gòu)的概念,使用javascript實(shí)現(xiàn)了樹(shù),如有紕漏,歡迎批評(píng)指正。 ...

    Dean 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<