js實現完全排序二叉樹、二叉搜尋樹

燦兒哈擦蘇發表於2019-07-08

完全二叉樹是效率很高的資料結構,完全二叉樹是由滿二叉樹而引出來的。
對於深度為K的,有n個結點的二叉樹,當且僅當其每一個結點都與深度
為K的滿二叉樹中編號從1至n的結點一一對應時稱之為完全二叉樹。

二叉查詢樹(Binary Search Tree),(又:二叉搜尋樹,二叉排序樹)
它或者是一棵空樹,或者是具有下列性質的二叉樹: 若它的左子樹不空,
則左子樹上所有結點的值均小於它的根結點的值; 若它的右子樹不空,
則右子樹上所有結點的值均大於它的根結點的值; 它的左、右子樹也分別為二叉排序樹。

排序二叉樹的實現考慮加入null的情況。

 //建立二叉樹
function Node(data,left,right){
    this.val = data;
    this.left = left;
    this.right = right;
}
 Node.prototype.show = function(){
    return this.val;
}

function BST(){
    this.root = null;
}

//查詢二叉樹
BST.prototype.insert = function(data){
	if(data === null){
		return false
	}
    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.val){
                current = current.left;
                if(current == null){
                    parent.left = node;
                    break;
                }
            }else{
                current = current.right;
                if(current == null){
                    parent.right = node;
                    break;
                }
            }
        }
    }
}

//迭代方式建立普通給定陣列順序二叉樹
BST.prototype.create = function(charecters){
	var len = charecters.length ;  //陣列的長度
    var nodes = new Array(); //建立一個臨時陣列,用於存放二叉樹節點
    //迴圈建立二叉樹節點存放到陣列中
    for (var i = 0 ; i < len ; i++) {
    	if(charecters[i]){
    		var node = new Node(charecters[i],null,null);
    		nodes.push(node);
    	}else{
    		nodes.push(null)
    	}
    }
	var index = 0;//索引從0開始
	this.root = nodes[0];
	// [ 5 , 1 , 4 , null , null , 3 , 6 , 6 , null , 7]
	//1.     ^ 5 ^
	//2.              ^   1   ^
	//3.                           ^ 4 ^
	//4.                                   ^ 3 ^
	//count計算有null佔位的情況
	var count = 0 
	//迴圈建立二叉樹子節點的引用
    while(index < len) {
    	
        if(nodes[index]){
        	var leftIndex = 2*(index-count)+1,              //當前節點左孩子索引
        		rightIndex = 2*(index-count)+2;             //當前節點右孩子索引
        	//給當前節點新增左孩子
        	nodes[index].left = nodes[leftIndex];
        	//給當前節點新增右孩子
        	nodes[index].right = nodes[rightIndex];
        }else{
        	count++;
        }
        index++;
    }
}

//遞迴方式建立普通給定陣列順序二叉樹
BST.prototype.createRecurrence = function(charecters){
    this.root = new Node(charecters[0],null,null);
	var innerfun = function(nodes,i){
		var leftIndex = 2*i+1,
			rightIndex = 2*i+2;
		if(leftIndex < charecters.length){
			var node = new Node(charecters[leftIndex],null,null);
			nodes.left = node;
			innerfun(node,leftIndex);
		}
		if(rightIndex < charecters.length){
			var node = new Node(charecters[rightIndex],null,null);
			nodes.right = node;
			innerfun(node,rightIndex);
		}
	}
	innerfun(this.root,0)
}

//中序遍歷
BST.prototype.inOrder = function(node){
    if(node){
        this.inOrder(node.left);
        console.log(node.show() + " ");
        this.inOrder(node.right);
    }
}

//堆疊  後進先出  將當前結點的孩子全部遍歷結束,在遍歷同一級的節點  深度優先搜尋
BST.prototype.deepTraversal = function(node){
	var list = []
	var stack = []
	stack.push(node)
	while(stack.length !== 0){
		var item = stack.pop()
		list.push(item.val)
		if(item.right){
			stack.push(item.right)
		}
		if(item.left){
			stack.push(item.left)
		}
	}
	return list
}

//佇列   先進先出  根  第一層子節點  第二層子節點  左到右依次遍歷  廣度優先搜尋
BST.prototype.wideTraversal = function(node){
	var list = []
	var stack = []
	stack.push(node)
	while(stack.length !== 0){
		var item = stack.shift()
		list.push(item.val)
		if(item.left){
			stack.push(item.left)
		}
		if(item.right){
			stack.push(item.right)
		}
	}
	return list
}
複製程式碼

呼叫方式1:迭代生成
var bst  = new BST();
var nums = [5,1,4,null,null,3,6,6,null,7]
bst.create(nums);
console.log(bst)

複製程式碼

呼叫方式2:遞迴生成
var bst  = new BST();
var nums = [5,1,4,null,null,3,6,6,null,7]
bst.createRecurrence(nums);
console.log(bst)複製程式碼

呼叫方式3:
var bst  = new BST();
var nums = [5,1,4,null,null,3,6,6,null,7]
for(var i = 0;i < nums.length;i ++){
  bst.insert(nums[i]);
}
console.log(bst)

複製程式碼


相關文章