中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

javascript多叉樹經典操作的方法

發布時間:2022-04-28 14:40:03 來源:億速云 閱讀:187 作者:iii 欄目:大數據

本篇內容主要講解“javascript多叉樹經典操作的方法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“javascript多叉樹經典操作的方法”吧!

多叉樹可以實現復雜的數據結構的存儲,通過遍歷方法可以方便高效的查找數據,提高查找的效率,同時方便管理節點數據。javascript的DOM其實就是以多叉樹的形式存儲的。下面用javascript來實現多叉樹的數據結構

1、創造一個節點

數據是以節點的形式存儲的:

class Node {
  constructor(data) {
    this.data = data;
    this.parent = null;
    this.children = [];
  }
}

2、創造樹

樹用來連接節點,就像真實世界樹的主干一樣,延伸著很多分支

class MultiwayTree {
  constructor() {
    this._root = null;
  }
}

3、添加一個節點

function add(data, toData, traversal) {
  let node = new Node(data)
  // 第一次添加到根節點
  // 返回值為this,便于鏈式添加節點
  if (this._root === null) {
    this._root = node;
    return this;
  }
  let parent = null,
    callback = function(node) {
      if (node.data === toData) {
        parent = node;
        return true;
      }
    };
  // 根據遍歷方法查找父節點(遍歷方法后面會講到),然后把節點添加到父節點
  // 的children數組里
  // 查找方法contains后面會講到
  this.contains(callback, traversal);
  if (parent) {
    parent.children.push(node);
    node.parent = parent;
    return this;
  } else {
    throw new Error('Cannot add node to a non-existent parent.');
  }
}

4、深度優先遍歷

深度優先會盡量先從子節點查找,子節點查找完再從兄弟節點查找,適合數據深度比較大的情況,如文件目錄

function traverseDF(callback) {
  let stack = [], found = false;
  stack.unshift(this._root);
  let currentNode = stack.shift();
  while(!found && currentNode) {
    // 根據回調函數返回值決定是否在找到第一個后繼續查找
    found = callback(currentNode) === true ? true : false;
    if (!found) {
      // 每次把子節點置于堆棧最前頭,下次查找就會先查找子節點
      stack.unshift(...currentNode.children);
      currentNode = stack.shift();
    }
  }
}

5、廣度優先遍歷

廣度優先遍歷會優先查找兄弟節點,一層層往下找,適合子項較多情況,如公司崗位級別

function traverseBF(callback) {
  let queue = [], found = false;
  queue.push(this._root);
  let currentNode = queue.shift();
  while(!found && currentNode) {
    // 根據回調函數返回值決定是否在找到第一個后繼續查找
    found = callback(currentNode) === true ? true : false;
    if (!found) {
      // 每次把子節點置于隊列最后,下次查找就會先查找兄弟節點
      queue.push(...currentNode.children)
      currentNode = queue.shift();
    }
  }
}

6、包含節點

function contains(callback, traversal) {
  traversal.call(this, callback);
}

回調函數算法可自己根據情況實現,靈活度較高

7、移除節點

// 返回被移除的節點
function remove(data, fromData, traversal) {
  let parent = null,
    childToRemove = null,
    callback = function(node) {
      if (node.data === fromData) {
        parent = node;
        return true;
      }
    };
  this.contains(callback, traversal);
  if (parent) {
    let index = this._findIndex(parent.children, data);
    if (index < 0) {
      throw new Error('Node to remove does not exist.');
    } else {
      childToRemove = parent.children.splice(index, 1);
    }
  } else {
    throw new Error('Parent does not exist.');
  }
  return childToRemove;
}

_findIndex實現:

function _findIndex(arr, data) {
  let index = -1;
  for (let i = 0, len = arr.length; i < len; i++) {
    if (arr[i].data === data) {
      index = i;
      break;
    }
  }
  return index;
}

完整算法

class Node {
  constructor(data) {
    this.data = data;
    this.parent = null;
    this.children = [];
  }
}
class MultiwayTree {
  constructor() {
    this._root = null;
  }
  //深度優先遍歷
  traverseDF(callback) {
    let stack = [], found = false;
    stack.unshift(this._root);
    let currentNode = stack.shift();
    while(!found && currentNode) {
      found = callback(currentNode) === true ? true : false;
      if (!found) {
        stack.unshift(...currentNode.children);
        currentNode = stack.shift();
      }
    }
  }
  //廣度優先遍歷
  traverseBF(callback) {
    let queue = [], found = false;
    queue.push(this._root);
    let currentNode = queue.shift();
    while(!found && currentNode) {
      found = callback(currentNode) === true ? true : false;
      if (!found) {
        queue.push(...currentNode.children)
        currentNode = queue.shift();
      }
    }
  }
  contains(callback, traversal) {
    traversal.call(this, callback);
  }
  add(data, toData, traversal) {
    let node = new Node(data)
    if (this._root === null) {
      this._root = node;
      return this;
    }
    let parent = null,
      callback = function(node) {
        if (node.data === toData) {
          parent = node;
          return true;
        }
      };
    this.contains(callback, traversal);
    if (parent) {
      parent.children.push(node);
      node.parent = parent;
      return this;
    } else {
      throw new Error('Cannot add node to a non-existent parent.');
    }
  }
  remove(data, fromData, traversal) {
    let parent = null,
      childToRemove = null,
      callback = function(node) {
        if (node.data === fromData) {
          parent = node;
          return true;
        }
      };
    this.contains(callback, traversal);
    if (parent) {
      let index = this._findIndex(parent.children, data);
      if (index < 0) {
        throw new Error('Node to remove does not exist.');
      } else {
        childToRemove = parent.children.splice(index, 1);
      }
    } else {
      throw new Error('Parent does not exist.');
    }
    return childToRemove;
  }
  _findIndex(arr, data) {
    let index = -1;
    for (let i = 0, len = arr.length; i < len; i++) {
      if (arr[i].data === data) {
        index = i;
        break;
      }
    }
    return index;
  }
}

控制臺測試代碼

var tree = new MultiwayTree();
tree.add('a')
  .add('b', 'a', tree.traverseBF)
  .add('c', 'a', tree.traverseBF)
  .add('d', 'a', tree.traverseBF)
  .add('e', 'b', tree.traverseBF)
  .add('f', 'b', tree.traverseBF)
  .add('g', 'c', tree.traverseBF)
  .add('h', 'c', tree.traverseBF)
  .add('i', 'd', tree.traverseBF);
console.group('traverseDF');
tree.traverseDF(function(node) {
  console.log(node.data);
});
console.groupEnd('traverseDF');
console.group('traverseBF');
tree.traverseBF(function(node) {
  console.log(node.data);
});
console.groupEnd('traverseBF');
// 深度優先查找
console.group('contains1');
tree.contains(function(node) {
  console.log(node.data);
  if (node.data === 'f') {
    return true;
  }
}, tree.traverseDF);
console.groupEnd('contains1')
// 廣度優先查找
console.group('contains2');
tree.contains(function(node) {
  console.log(node.data);
  if (node.data === 'f') {
    return true;
  }
}, tree.traverseBF);
console.groupEnd('contains2');
tree.remove('g', 'c', tree.traverseBF);

這里使用在線HTML/CSS/JavaScript代碼運行工具:http://tools.jb51.net/code/HtmlJsRun測試運行效果如下:

javascript多叉樹經典操作的方法

到此,相信大家對“javascript多叉樹經典操作的方法”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

西宁市| 永福县| 喀喇沁旗| 松潘县| 阿坝县| 晋宁县| 增城市| 阳东县| 隆昌县| 凤阳县| 凤台县| 曲周县| 平武县| 砀山县| 华宁县| 阿拉善右旗| 上高县| 左贡县| 依兰县| 扶绥县| 新闻| 阜平县| 蓝山县| 峨眉山市| 尼勒克县| 西城区| 陇西县| 天祝| 临清市| 若尔盖县| 吉首市| 兴仁县| 南川市| 通渭县| 益阳市| 安图县| 浪卡子县| 白水县| 清流县| 扶余县| 乐亭县|