當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
JavaScript--数据结构与算法之二叉树
生活随笔
收集整理的這篇文章主要介紹了
JavaScript--数据结构与算法之二叉树
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
樹是一種非線性的數據結構,以分層的方式存儲數據。
二叉樹:查找非常快,而且二叉樹添加或者刪除元素也非常快。
形象的可以描述為組織結構圖,用來描述一個組織的結構。樹是由邊連接的點組成。
樹的一些基本概念:
根節點:一棵樹最上面的節點。
父節點:一個節點下面連接多個節點,該節點是父節點。
子節點:父節點下面的節點。(一個節點可以有0,1,或者多個子節點)
葉子節點:沒有任何子節點的節點。
路徑:從一個節點到另一個節點的這一組邊。
樹的遍歷:以某種特定順序訪問樹中所有的節點。
樹的分層:根節點是0層,它的子節點是第一層以此類推。
樹的深度:書的層數就是深度。
鍵:每個節點都有一個與之相關的值。
二叉樹和二叉查找樹
二叉樹:一種特殊的樹,子節點不超過兩個將子樹節點的個數限定為2,可以寫出高效的程序在樹中插入、查找、刪除數據。
左右節點:父節點的兩個子節點。
二叉查找樹:是一種特殊的二叉樹,相對較小的節點存在左節點,較大的存在右節點。這一特性是的查找的效率很高。 1、實現二叉查找樹:
又節點組成,定義的第一個對象是Node,和鏈表的Node對象相似。
Node對象既能保存保存數據,也能保存和其他節點鏈接(left,right),show()用來顯示保存在節點中的數據。 function Node(data,left,right) {this.data = data;this.left = left;this.right = right;//this.show = show; }Node.prototype.show = function() {return this.data;};
該類只有一個數據成員,表示二叉樹查找樹根節點的Node對象,初始化null;
BST有一個insert()方法,用來插入新節點,有點復雜,首先創建一個Node對象,將對象傳入該數據中。檢查BST是否有根結點,如果沒有則是新樹,該節點是根節點。否則待插入節點不是根節點,需要遍歷BST,找到插入的適當位置。該過程類似與遍歷鏈表。用一個變量存儲當前結點,一層層地遍歷BST。進入BST以后,下一步就是決定將節點放在什么地方,找到正確的插入點。
1)設置根節點為當前節點。
2)如果待插入節點保存的數據小于當前節點,則設置新的當前節點為原節點的左節點;反之4)
3)如果當前節點的左節點為null,就將新的節點插入這個位置,退出循環;反之執行下一次循環。
4)設置新的當前節點為原節點的右節點。
5)如果當前節點的右節點為null,就將新的節點插入這個位置,推出循環;反之執行下一次循環; ? function BST() {this.root = null;//this.insert = insert;this.preOrder = preOrder;//先序遍歷this.inOrder = inOrder;//中序遍歷this.postOrder = postOrder;//后序遍歷 }BST.prototype.insert = function(data) {var _node = new Node(data,null,null);if(this.root == null) {this.root = _node;}else{var _current = this.root;var _parent;while(true) {_parent = _current;if(data < _current.data) {_current = _current.left;if(_current == null) {_parent.left = _node;break;}}else{_current = _current.right;if(_current == null) {_parent.right = _node;break;}}}}}; 2、遍歷二叉樹
方式:先序,中序,后序。(都是以根為參照訪問)
先序:先訪問根節點,再以升序的方式訪問左子樹和右子樹。
中序:以升序的方式訪問左中右的次序。
后序:先訪問葉子節點,從左子樹到右子樹再到根節點。 //先序遍歷preOrderfunction preOrder (node) {if(!(node == null)) {console.log(node.show());preOrder(node.left);preOrder(node.right);}}//test...var bst = new BST();bst.insert(23);bst.insert(45);bst.insert(16);bst.insert(37);bst.insert(3);bst.insert(99);bst.insert(22);preOrder(bst.root);//中序遍歷inOrderfunction inOrder (node) {if(!(node == null)) {inOrder(node.left);console.log(node.show());inOrder(node.right);}}console.log("--------------------");inOrder(bst.root);//后序遍歷inOrderfunction postOrder (node) {if(!(node == null)) {postOrder(node.left);postOrder(node.right);console.log(node.show());}}console.log("--------------------");postOrder(bst.root); //完整代碼: ~(function() {function Node(data,left,right) {this.data = data;this.left = left;this.right = right;//this.show = show; }Node.prototype.show = function() {return this.data;};function BST() {this.root = null;//this.insert = insert;this.preOrder = preOrder;//先序遍歷this.inOrder = inOrder;//中序遍歷this.postOrder = postOrder;//后序遍歷 }BST.prototype.insert = function(data) {var _node = new Node(data,null,null);if(this.root == null) {this.root = _node;}else{var _current = this.root;var _parent;while(true) {_parent = _current;if(data < _current.data) {_current = _current.left;if(_current == null) {_parent.left = _node;break;}}else{_current = _current.right;if(_current == null) {_parent.right = _node;break;}}}}};//先序遍歷preOrderfunction preOrder (node) {if(!(node == null)) {console.log(node.show());preOrder(node.left);preOrder(node.right);}}//中序遍歷inOrderfunction inOrder (node) {if(!(node == null)) {inOrder(node.left);console.log(node.show());inOrder(node.right);}}//后序遍歷inOrderfunction postOrder (node) {if(!(node == null)) {postOrder(node.left);postOrder(node.right);console.log(node.show());}}})();
2)查找最大值;
3)查找給定值。 最大最小值的查找比較簡單,只要遍歷到最左,最右即可。 BST.prototype.getMin = function() {var _current = this.root;while(!(_current.left == null)) {_current = _current.left;}return _current.data;};BST.prototype.getMax = function () {var _current = this.root;while(!(_current.right == null)) {_current = _current.right;}return _current.data;};console.log("-----------");console.log( bst.getMin() );console.log( bst.getMax() ); 查找給定值:find();?需要比較該值和當前節點上的值的大小。通過比較大小,確定左遍歷還是右遍歷。 BST.prototype.find = function(data) {var _current = this.root;while(_current != null) {if(_current.data == data) {return _current;}else if(data < _current.data) {_current = _current.left;}else{_current = _current.right;}}return null;//沒找到返回null };console.log("-----------");console.log( bst.find(99) );
2)刪除只有一個子節點
3)刪除包含兩個子節點 刪除時要刪除數據和刪除節點。
算法具體過程:
先判斷當前節點是否包含待刪除的數據,如果包含則刪除該節點。如果不包含則比較當前節點上的數據和待刪除的數據(刪除根節點)。如果不包含,則比較當前節點的數據和待刪除的數據。如果待刪除數據小于當前節點上的數據,則移至當前結點的左子樹節點繼續比較;如果大于當前節點上的數據,則移至當前節點的右子節點繼續比較。
葉子節:只需要將從父節點指向它的鏈接指向null;
刪除節點只包含一個子節點:原本只想他的節點就的做些調整,使其指向它的子節點。
刪除包含兩個子節點:一種是查找待刪除節點左子樹上的最大值,要么查找其右子樹上的最小值。
這個過程有兩個方法完成,一個刪除數據remove();,一個刪除節點removeNode(); function remove(data) {root = removeNode(this.root,data);}function getSmallest(node) {if (node.left == null) {return node;}else {return getSmallest(node.left);}}function removeNode(node,data) {if(node == null) {return null;}if(data == node.data) {if(node.left == null && node.right == null) {//葉子節點return null;}if(node.left == null) {//沒有左子樹return node.right;}if(node.right == null) {//沒有右子樹return node.left;}//有兩個子節點的節點var _tempNode = getSmallest(node.right);//采用右子樹上的最小值node.data = _tempNode.data;node.right = removeNode(node.right,_tempNode.data);return node;}else if(data < node.data) {node.left = removeNode(node.left,data);return node;}else {node.right = removeNode(node.right,data);return node;}}//bst.remove(3); preOrder(bst.root);//console.log( bst.show() );
二叉樹:查找非常快,而且二叉樹添加或者刪除元素也非常快。
形象的可以描述為組織結構圖,用來描述一個組織的結構。樹是由邊連接的點組成。
樹的一些基本概念:
根節點:一棵樹最上面的節點。
父節點:一個節點下面連接多個節點,該節點是父節點。
子節點:父節點下面的節點。(一個節點可以有0,1,或者多個子節點)
葉子節點:沒有任何子節點的節點。
路徑:從一個節點到另一個節點的這一組邊。
樹的遍歷:以某種特定順序訪問樹中所有的節點。
樹的分層:根節點是0層,它的子節點是第一層以此類推。
樹的深度:書的層數就是深度。
鍵:每個節點都有一個與之相關的值。
二叉樹和二叉查找樹
二叉樹:一種特殊的樹,子節點不超過兩個將子樹節點的個數限定為2,可以寫出高效的程序在樹中插入、查找、刪除數據。
左右節點:父節點的兩個子節點。
二叉查找樹:是一種特殊的二叉樹,相對較小的節點存在左節點,較大的存在右節點。這一特性是的查找的效率很高。 1、實現二叉查找樹:
又節點組成,定義的第一個對象是Node,和鏈表的Node對象相似。
Node對象既能保存保存數據,也能保存和其他節點鏈接(left,right),show()用來顯示保存在節點中的數據。 function Node(data,left,right) {this.data = data;this.left = left;this.right = right;//this.show = show; }Node.prototype.show = function() {return this.data;};
二叉樹的創建:binary search tree
二叉樹的創建:binary search tree該類只有一個數據成員,表示二叉樹查找樹根節點的Node對象,初始化null;
BST有一個insert()方法,用來插入新節點,有點復雜,首先創建一個Node對象,將對象傳入該數據中。檢查BST是否有根結點,如果沒有則是新樹,該節點是根節點。否則待插入節點不是根節點,需要遍歷BST,找到插入的適當位置。該過程類似與遍歷鏈表。用一個變量存儲當前結點,一層層地遍歷BST。進入BST以后,下一步就是決定將節點放在什么地方,找到正確的插入點。
1)設置根節點為當前節點。
2)如果待插入節點保存的數據小于當前節點,則設置新的當前節點為原節點的左節點;反之4)
3)如果當前節點的左節點為null,就將新的節點插入這個位置,退出循環;反之執行下一次循環。
4)設置新的當前節點為原節點的右節點。
5)如果當前節點的右節點為null,就將新的節點插入這個位置,推出循環;反之執行下一次循環; ? function BST() {this.root = null;//this.insert = insert;this.preOrder = preOrder;//先序遍歷this.inOrder = inOrder;//中序遍歷this.postOrder = postOrder;//后序遍歷 }BST.prototype.insert = function(data) {var _node = new Node(data,null,null);if(this.root == null) {this.root = _node;}else{var _current = this.root;var _parent;while(true) {_parent = _current;if(data < _current.data) {_current = _current.left;if(_current == null) {_parent.left = _node;break;}}else{_current = _current.right;if(_current == null) {_parent.right = _node;break;}}}}}; 2、遍歷二叉樹
方式:先序,中序,后序。(都是以根為參照訪問)
先序:先訪問根節點,再以升序的方式訪問左子樹和右子樹。
中序:以升序的方式訪問左中右的次序。
后序:先訪問葉子節點,從左子樹到右子樹再到根節點。 //先序遍歷preOrderfunction preOrder (node) {if(!(node == null)) {console.log(node.show());preOrder(node.left);preOrder(node.right);}}//test...var bst = new BST();bst.insert(23);bst.insert(45);bst.insert(16);bst.insert(37);bst.insert(3);bst.insert(99);bst.insert(22);preOrder(bst.root);//中序遍歷inOrderfunction inOrder (node) {if(!(node == null)) {inOrder(node.left);console.log(node.show());inOrder(node.right);}}console.log("--------------------");inOrder(bst.root);//后序遍歷inOrderfunction postOrder (node) {if(!(node == null)) {postOrder(node.left);postOrder(node.right);console.log(node.show());}}console.log("--------------------");postOrder(bst.root); //完整代碼: ~(function() {function Node(data,left,right) {this.data = data;this.left = left;this.right = right;//this.show = show; }Node.prototype.show = function() {return this.data;};function BST() {this.root = null;//this.insert = insert;this.preOrder = preOrder;//先序遍歷this.inOrder = inOrder;//中序遍歷this.postOrder = postOrder;//后序遍歷 }BST.prototype.insert = function(data) {var _node = new Node(data,null,null);if(this.root == null) {this.root = _node;}else{var _current = this.root;var _parent;while(true) {_parent = _current;if(data < _current.data) {_current = _current.left;if(_current == null) {_parent.left = _node;break;}}else{_current = _current.right;if(_current == null) {_parent.right = _node;break;}}}}};//先序遍歷preOrderfunction preOrder (node) {if(!(node == null)) {console.log(node.show());preOrder(node.left);preOrder(node.right);}}//中序遍歷inOrderfunction inOrder (node) {if(!(node == null)) {inOrder(node.left);console.log(node.show());inOrder(node.right);}}//后序遍歷inOrderfunction postOrder (node) {if(!(node == null)) {postOrder(node.left);postOrder(node.right);console.log(node.show());}}})();
?3、二叉樹上的查找:
1)查找最小值;2)查找最大值;
3)查找給定值。 最大最小值的查找比較簡單,只要遍歷到最左,最右即可。 BST.prototype.getMin = function() {var _current = this.root;while(!(_current.left == null)) {_current = _current.left;}return _current.data;};BST.prototype.getMax = function () {var _current = this.root;while(!(_current.right == null)) {_current = _current.right;}return _current.data;};console.log("-----------");console.log( bst.getMin() );console.log( bst.getMax() ); 查找給定值:find();?需要比較該值和當前節點上的值的大小。通過比較大小,確定左遍歷還是右遍歷。 BST.prototype.find = function(data) {var _current = this.root;while(_current != null) {if(_current.data == data) {return _current;}else if(data < _current.data) {_current = _current.left;}else{_current = _current.right;}}return null;//沒找到返回null };console.log("-----------");console.log( bst.find(99) );
?4、刪除二叉查找樹上的節點
刪除操作相對復雜,分為三種情況 1)刪除葉子節點(沒有子節點的節點)2)刪除只有一個子節點
3)刪除包含兩個子節點 刪除時要刪除數據和刪除節點。
算法具體過程:
先判斷當前節點是否包含待刪除的數據,如果包含則刪除該節點。如果不包含則比較當前節點上的數據和待刪除的數據(刪除根節點)。如果不包含,則比較當前節點的數據和待刪除的數據。如果待刪除數據小于當前節點上的數據,則移至當前結點的左子樹節點繼續比較;如果大于當前節點上的數據,則移至當前節點的右子節點繼續比較。
葉子節:只需要將從父節點指向它的鏈接指向null;
刪除節點只包含一個子節點:原本只想他的節點就的做些調整,使其指向它的子節點。
刪除包含兩個子節點:一種是查找待刪除節點左子樹上的最大值,要么查找其右子樹上的最小值。
這個過程有兩個方法完成,一個刪除數據remove();,一個刪除節點removeNode(); function remove(data) {root = removeNode(this.root,data);}function getSmallest(node) {if (node.left == null) {return node;}else {return getSmallest(node.left);}}function removeNode(node,data) {if(node == null) {return null;}if(data == node.data) {if(node.left == null && node.right == null) {//葉子節點return null;}if(node.left == null) {//沒有左子樹return node.right;}if(node.right == null) {//沒有右子樹return node.left;}//有兩個子節點的節點var _tempNode = getSmallest(node.right);//采用右子樹上的最小值node.data = _tempNode.data;node.right = removeNode(node.right,_tempNode.data);return node;}else if(data < node.data) {node.left = removeNode(node.left,data);return node;}else {node.right = removeNode(node.right,data);return node;}}//bst.remove(3); preOrder(bst.root);//console.log( bst.show() );
?
轉載于:https://www.cnblogs.com/intelwisd/p/7755534.html
總結
以上是生活随笔為你收集整理的JavaScript--数据结构与算法之二叉树的全部內容,希望文章能夠幫你解決所遇到的問題。