JS中广度深度优先遍历应用拷贝函数

1,118 阅读1分钟

广度优先遍历和深度优先遍历应用——实现对象深拷贝

//判断要复制的对象的类型,仅考虑对象和数组两种复杂数据类型
function getEmpty(obj) {
    if (Object.prototype.toString.call(obj) === '[object Object]') {
        return {};
    } else if (Object.prototype.toString.call(obj) === '[object Array]') {
        return [];
    }
    return obj; //基本数据类型处理
}
//广度优先遍历
function bfsCopy(origin) {
    let queue = [];
    let map = new Map(); //记录出现过的对象,用于处理环
    let ans = getEmpty(origin);
    if (ans !== origin) {
        queue.push([origin, ans]);
        map.set(origin, ans);
    }
    while (queue.length) {
        let [ori, ans] = queue.shift();
        for (let key in ori) {
            if (map.get(ori[key])) { //说明此时的键值已经被设置过了,此时不需要再对其内部进行递归操作,否则会陷入死循环
                ans[key] = map.get(ori[key]);
                continue;
            }
            ans[key] = getEmpty(ori[key]);
            if (ans[key] !== ori[key]) {
                queue.push(ori[key]);
                map.set(ori[key], ans[key]);
            }
        }
    }
    return ans;
}
//深度优先遍历,递归
dfsCopy1.prototype.map = new Map(); //再原型中存储变量map使得每层递归调用中都能访问到map
function dfsCopy1(origin) {
    let ans = getEmpty(origin);
    dfsCopy1.prototype.map.set(origin, ans);
    if (ans === origin) {
        return ans;
    }
    for (let key in origin) {
        if (dfsCopy1.prototype.map.get(origin[key])) { //环处理
            ans[key] = dfsCopy1.prototype.map.get(origin[key]);
            continue;
        }
        ans[key] = dfsCopy1(origin[key]);
    }
    return ans;
}
//深度优先遍历非递归
function dfsCopy2(origin) {
    let stack = [];
    let map = new Map();
    let ans = getEmpty(origin);
    if (ans === origin) return ans;
    stack.push([origin, ans]);
    while (stack.length) {
        let [childori, childans] = stack.pop();
        for (let key in childori) {
            if (map.get(childori[key])) { //环处理
                childans[key] = childori[key];
                continue;
            }
            childans[key] = getEmpty(childori[key]);
            if (childans[key] !== childori[key]) {
                stack.push([childori[key], childans[key]]);
                map.set(childori[key], childans[key]);
            }
        }
    }
    return ans;
}
let obj = {
    a: 2,
    b: {
        c: 3
    }
}
obj.b.d = obj;

console.log(bfsCopy(obj.b.d.a)); // 2