用JS实现栈队列二叉树遍历等操作

Posted 开到荼蘼223's

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用JS实现栈队列二叉树遍历等操作相关的知识,希望对你有一定的参考价值。

栈主要体现在后进先出,在一端进行插入和删除的数据结构,表尾端称为栈顶(top),表头端称为栈底(bottom),因为栈限定在表尾进行插入或者删除,所以栈又被称为后进先出的线性表

// 栈的构造函数
function Stack()
    var items = [];
    // 将元素送入栈,放置于数组的最后一位
    this.push = function(element)
        items.push(element);
    
    // 弹出栈顶元素
    this.pop = function(element)
        return items.pop();
    
    // 查看栈顶元素
    this.peek = function()
        return items[items.length-1];
    
    // 确定栈是否为空
    this.isAmpty = function()
        return items.length == 0;
    
    // 清空栈中所有内容
    this.clear = function()
        items = [];
    
    // 返回栈的长度
    this.size = function()
        return items.length;
    
    // 以字符串显示栈中所以有的内容
    this.print = function()
        console.log(items.toString());
    

队列 先进先出,只允许在一端插入,在另一端删除,插入的一端称为队尾,删除的一端称为队头

// 队列的构造函数
function Queue()
    var items = [];
    // 将元素推入队列
    this.enqueue = function(ele)
        items.push(ele);
    
    // 将队列中的第一个元素弹出
    this.dequeue = function()
        return items.shift();
    
    // 查看队列的第一个元素
    this.front = function()
        return items[0];
    
    // 确定队列是否为空
    this.isAmpty = function()
        return items.length === 0;
    
    this.size = function()
        return items.length;
    
    // 清空队列中所有内容
    this.clear = function()
        items = [];
    
    // 以字符串显示队列中所有内容
    this.print = function()
        console.log(items.toString())
    


  /* 击鼓传花的小游戏
   * @param  Array nameList 参与人员列表
   * @param  Number num      在循环中要被弹出的位置
   * @return String          返回赢家(也就是最后活下来的那个)
   */
  function hotPotato(nameList, num) 
    var queue = new Queue();  
    for (var i = 0; i < nameList.length; i++) 
      queue.enqueue(nameList[i]);
      
    var eliminated = '';  
    while (queue.size() > 1) 
      for (var i = 0; i < num; i++) 
        queue.enqueue(queue.dequeue());
      
      eliminated = queue.dequeue();
      console.log(eliminated + " Get out!")
    
    return queue.dequeue();
  
  var nameList = ['小明', '小红', '小王', '小强']
  hotPotato(nameList,3);

二叉树 每个节点都最多有两个节点,分别为左子节点和右子节点,满足这个条件的树就是二叉树

构建二叉树:在js中以对象的方式存放二叉树中各个节点的值

遍历:不重复的访问二叉树中的每一个节点每一个节点

  • 前序遍历:root-left-right
  • 中序遍历:let-root-right
  • 后序遍历:right-left-root
var tree = 
    value: 1,
    left:
       value: 4,
       left: 
           value: 6
       ,
       right: 
           value: 9,
           left: 
               value: 15
           
       
    ,
    right: 
        value: 35,
        left: 
            value: 30,
            right: 
                value: 45
            
        
    


/**
 * 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
 * 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
 * 例如输入前序遍历序列1,2,4,7,3,5,6,8和中序遍历列4,7,2,1,5,3,8,6,
 * 则重建二叉树并返回。
 * 
 *   输入:  前序:[1,2,3,4,5,6,7],
 * 
 *           中序:[3,2,4,1,6,5,7]
   
    输出:
           层次遍历: [1,2,5,3,4,6,7]
 */
 class binaryTree 
    constructor(v,l,r)
        this.val = v;
        this.left = l;
        this.right = r
    


/**
 * 已知前序序列、中序序列
 * @param * pre 表示前序遍历序列
 * @param * next 表示中序遍历序列
 */
function reConstructBinaryTree(pre,next) 	 
    // 递归出口
    if(pre.length == 0 || next.length == 0 || pre.length != next.length) 
        return null;
    
    // 拿到根结点
    let root = new binaryTree(pre[0]);
    
    // 找的根结点在中序遍历中的位置
    let i = 0;
    while(next[i] != root.val) 
        i++;
    
    //确定左子树前序遍历长度
    preLeft = new Array(i);
    //确定左子树中序遍历长度
    inLeft = new Array(i);
  
    //确定右子树前序遍历长度
    let preRight = new Array(next.length - i -1);
    //确定右子树中序遍历长度
    let inRight = new Array(next.length - i -1);
     
    // 遍历依次拿到左右子树  前中序遍历的值
    for(let j = 0 ; j<next.length ;j++) 
        if(j < i) 
            preLeft[j] = pre[j+1];
            inLeft[j] = next[j];
        else if(j > i) 
            preRight[j-i-1] = pre[j];
            inRight[j-i-1] = next[j];
        
    
    // 递归
    root.left = reConstructBinaryTree(preLeft,inLeft);
    root.right = reConstructBinaryTree(preRight,inRight);
    return root;


var pre_arr = []  //存放前序遍历序列
var in_arr =[] //存放中序遍历序列
var post_arr = [] //存放后序遍历序列
var level_arr = [] //存放层次遍历序列

/**
 * D:访问根结点,L:遍历根结点的左子树,R:遍历根结点的右子树。
 * 前序遍历:DLR
 */
var preOrder = function(node)  
    if(node)
        pre_arr.push(node.val)
        preOrder(node.left)
        preOrder(node.right)
    

/**
 * D:访问根结点,L:遍历根结点的左子树,R:遍历根结点的右子树。
 * 中序遍历:LDR
 */
var inOrder = function (node)   
    if (node) 
     inOrder(node.left);  
     in_arr.push(node.val);
     inOrder(node.right);
    

/**
 * D:访问根结点,L:遍历根结点的左子树,R:遍历根结点的右子树。
 * 后序遍历:LRD
 */
var postOrder = function (node)  
    if (node) 
     postOrder(node.left);
     postOrder(node.right);  
     post_arr.push(node.val);
    


/**
 * 广度优先遍历(层次遍历)
    广度优先遍历是从二叉树的第一层(根结点)开始,自上至下逐层遍历;在同一层中,按照从左到右的顺序对结点逐一访问。
*/
var levelOrderTraversal = function(node)  
    if(!node)   
     throw new Error('Empty Tree')
     
    var que = []
    que.push(node) 
    while(que.length !== 0) 
     node = que.shift()  
     level_arr.push(node.val) 
     if(node.left) que.push(node.left)  
     if(node.right) que.push(node.right)
    

//测试
    a = [1,2,3,4,5,6,7];
	b = [3,2,4,1,6,5,7];
    root = reConstructBinaryTree(a,b);
    preOrder(root)
    console.log("前序序列是:"+pre_arr);
    inOrder(root)
    console.log("中序序列是:"+in_arr);
    postOrder(root)
    console.log("后序序列是:"+post_arr);
    levelOrderTraversal(root)
    console.log("层次序列是:"+level_arr);

以上是关于用JS实现栈队列二叉树遍历等操作的主要内容,如果未能解决你的问题,请参考以下文章

JS中的二叉树遍历

栈实现二叉树的先,中,后序遍历

算法刷题-二叉树的锯齿形层序遍历用栈实现队列_栈设计买卖股票的最佳时机 IV

js能力测试题21--42-牛客网

N日一篇——二叉树

N日一篇——二叉树