二叉搜尋樹JavaScript實現

來源:互聯網
上載者:User

標籤:max   rip   print   blog   insert   sso   ini   turn   中序遍曆   

* 什麼是二叉搜尋樹?其形式就是二叉樹,對於每個節點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;  }}

 

二叉搜尋樹JavaScript實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.