前天面試遇到一個多叉樹面試的題目,在這裡分享記錄一下。
題目:一個樹形的資料(如下資料),面試官給你一個
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: []
}
];
複製程式碼
比如說 我要id
是11112
的name
返回是靈芝
,請問你有幾種解法??
遞迴方法
這題目讓人看到這不就是考用遞迴的方法嘛,程式碼如下
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…