javaScript中常用的几种树结构遍历方式

139 阅读2分钟

节点树结构

// 要遍历的数据结构
let root = {
  name: "A",
  children: [
    {
      name: "B",
      children: [{ name: "B1" }, { name: "B2" }],
    },
    {
      name: "C",
      children: [{ name: "C1" }, { name: "C2" }],
    },
  ],
};
  • 深度优先遍历
// 递归
function treeToList(node){
  let result = [];
  function loop(node){
    if(node){
      result.push(node.name);
      let children = node.children || [];
      for(let i = 0; i < children.length;i++){
        loop(children[i])
      }
    }
  }
  loop(node)
  return result
}
treeToList(root)

// 非递归
function treeToList(node) {
  let stack = [];
  let result = [];
  if (node) {
    stack.push(node);
    while (stack.length) {
      let item = stack.pop();
      result.push(item.name);
      let children = item.children || [];
      for (let i = children.length - 1; i >= 0; i--) {
        stack.push(children[i]);
      }
    }
  }
  return result
}
console.log(traversal(tree));
  • 广度优先遍历
// 栈数据结构
function bfs(node) {
  let stack = [];
  stack.push(node);
  let current;
  while ((current = stack.shift())) {
    console.log(current.name);
    current.children &&
      current.children.forEach((child) => {
        stack.push(child);
      });
  }
}
bfs(root);

列表转树结构

// 要遍历的数据结构
const arr = [
  {
    id: 2,
    name: "部门B",
    parentId: 0,
  },
  {
    id: 3,
    name: "部门C",
    parentId: 1,
  },
  {
    id: 1,
    name: "部门A",
    parentId: 2,
  },
  {
    id: 4,
    name: "部门D",
    parentId: 1,
  },
  {
    id: 5,
    name: "部门E",
    parentId: 2,
  },
  {
    id: 6,
    name: "部门F",
    parentId: 3,
  },
  {
    id: 7,
    name: "部门G",
    parentId: 2,
  },
  {
    id: 8,
    name: "部门H",
    parentId: 4,
  },
];
  • 递归
function recursiveToTree(data) {
  function loop(key) {
    const res = [];
    data.forEach((item) => {
      if (item.parentId === key) {
        item.children = loop(item.id);
        res.push(item);
      }
    });
    return res;
  }
  return loop(0);
}
console.log(recursiveToTree(arr));
  • 栈数据结构
function listToTree(data) {
  let obj = {};
  let parentList = [];
  data.forEach((item) => {
    obj[item.id] = item;
  });
  data.forEach((item) => {
    const parent = obj[item.parentId];
    if (parent) {
      parent.children = parent.children || [];
      parent.children.push(item);
    } else {
      parentList.push(item);
    }
  });
  return parentList;
}
console.log(listToTree(arr));

业态 => 城市 => 门店 三级列表转树结构

// 数据源
let shopList = [
  {
    cityId: 2,
    sellerId: 3,
    city: "北京",
    shop: "万1店",
    shopId: "9456",
    seller: "哈哈哈",
    id: "1600631043031994393",
  },
  {
    cityId: 2,
    sellerId: 3,
    city: "北京",
    shopId: "9457",
    shop: "万2店",
    seller: "哈哈哈",
    id: "1600631043031994393",
  },
  {
    cityId: 5,
    sellerId: 3,
    city: "上海",
    shop: "万3店",
    shopId: "9458",
    seller: "哈哈哈",
    id: "1600631043031994393",
  },
  {
    cityId: 4,
    sellerId: 7,
    city: "福州",
    shopId: "9459",
    seller: "哇哇哇",
    shop: "万4店",
    id: "1600631043031994394",
  },
];
// 遍历
function transformTree(arr) {
  const sellerList = arr.map((item) => item.sellerId);
  const uniqueSellerList = Array.from(new Set(sellerList));

  const sellerTree = uniqueSellerList.map((seller) => {
    const currentSeller = arr.find((item) => item.sellerId === seller);
    // 构建一个业态对象
    const sellerObj = {
      seller: currentSeller.seller,
      sellerId: seller,
      cityVOS: [],
    };
    const cityArr = arr.filter((item) => item.sellerId === seller);
    const cityList = cityArr.map((item) => item.cityId);
    const uniqueCityList = Array.from(new Set(cityList));
    uniqueCityList.forEach((cityId) => {
      const currentCity = arr.find((item) => item.cityId === cityId);
      // 构建一个城市对象
      const cityObj = {
        city: currentCity.city,
        cityId,
        shopVOS: [],
      };
      const shopList = arr.filter((item) => item.cityId === cityId);
      cityObj.shopVOS.push(...shopList);
      sellerObj.cityVOS.push(cityObj);
    });
    return sellerObj;
  });
  return sellerTree;
}
console.log(transformTree(shopList));