面試題:給你個id,去拿到name,多叉樹遍歷

naice發表於2019-03-04

前天面試遇到一個多叉樹面試的題目,在這裡分享記錄一下。

題目:一個樹形的資料(如下資料),面試官給你一個id,然後拿到對應的name?

資料結構大概是這個樣子

var cityData = [
      {
        id: 1,
        name: `廣東省`,
        children: [
          {
            id: 11,
            name: `深圳`,
            children: [
              {
                id: 111,
                name: `寶安`,
                children: [
                  {
                    id: 1111,
                    name: `西鄉`,
                    children:[
                      {
                        id: 11111,
                        name: `坪洲`,
                        children:[]
                      },
                      {
                        id: 11112,
                        name: `靈芝`,
                        children:[]
                      }
                    ]
                  },
                  {
                    id: 1112,
                    name: `南山`,
                    children:[
                      {
                        id: 11121,
                        name: `科技園`,
                        children:[]
                      }
                    ]
                  }
                ]
              },
              {
                id: 112,
                name: `福田`,
                children: []
              }
            ]
          },
          {
            id: 12,
            name: `廣州`,
            children: [
              {
                id: 122,
                name: `白雲區`,
                children: [
                  {
                    id: 1222,
                    name: `白雲區`,
                    children: []
                  }
                ]
              },
              {
                id: 122,
                name: `珠海區`,
                children: []
              }
            ]
          }
        ]
      },
      {
        id: 2,
        name: `湖南省`,
        children: []
      }
    ];
複製程式碼

比如說 我要id11112name返回是靈芝,請問你有幾種解法??

遞迴方法

這題目讓人看到這不就是考用遞迴的方法嘛,程式碼如下


let result = ``

// 遞迴實現
const recursion = (cityData, id) => {
  // cityData資料為空的時候直接返回
  if (!cityData || !cityData.length) return;
  // 常規迴圈cityData
  for (let i = 0, len = cityData.length; i < len; i++) {
    const childs = cityData[i].children;
    
    // 如果匹配到id的話,就是我們要的結果
    if (cityData[i].id === id) {
      result = cityData[i].name
    }
    // 如果還有子節點,執行遞迴
    if(childs && childs.length > 0){
      recursion(childs, id);
    }
  }
  return result
};

const r = recursion(cityData, 11112);
console.log(r) // 靈芝

複製程式碼

oyes~~~完成了麼??面試官可能不滿意哦,下面還有幾種解法

廣度優先實現

let result = ``

const range = (cityData, id) => {
  if (!cityData || !cityData.length) return;
  // 定義一個資料棧
  let stack = [];

  let item = null;

  //先將第一層節點放入棧
  for (var i = 0, len = cityData.length; i < len; i++) {
    stack.push(cityData[i]);
  }

  while (stack.length) {
    // 將資料棧的第一個取出來
    item = stack.shift();
    // 如果符合就賦值給result
    if (item.id === id) {
      result = item.name
    }
    //如果該節點有子節點,繼續新增進入棧底
    if (item.children && item.children.length) {
      stack = stack.concat(item.children);
    }
  }
  return result
};

let r1 = range(cityData, 11112);

console.log(r1) // 靈芝

複製程式碼

深度優先實現

let result = ``

const deep = (cityData, id) => {
  // 沒有資料直接返回
  if (!cityData || !cityData.length) return;
  // 先定義一個資料棧
  let stack = []
  let item = null

  //先將第一層節點放入資料棧
  for (var i = 0, len = cityData.length; i < len; i++) {
    stack.push(cityData[i])
  }
  // 迴圈
  while (stack.length) {
    item = stack.shift()
    if (item.id === id) {
      result = item.name
    }
    //如果該節點有子節點,繼續新增進入棧頂
    if (item.children && item.children.length) {
      // 注意這裡調換了順序
      stack = item.children.concat(stack);
    }
  }
  return result
};

let r3 = deep(cityData, 11112)
console.log(r3) // 靈芝

複製程式碼

正則方式實現


const regular = (cityData, id) => {
  // 沒有資料直接返回
  if (!cityData || !cityData.length) return;
  // 資料轉成字串
  let cityStr = JSON.stringify(cityData)
  // 定義正則
  let reg = new RegExp(`"id":${id},"name":"([^\x00-\xff]+)",`)
  // 取到正則的子字串並返回
  return (cityStr.match(reg))[1]
}

let r4 = regular(cityData, 11112);

console.log(r4) // 靈芝

複製程式碼

這裡列舉了4種方法,應該還有很多種方法,大佬們有的話可以留言給我,先謝謝啦~~

安利一波部落格~~~github.com/naihe138/na…

相關文章