欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-23 19:43:56
...

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

//判断要复制的对象的类型,仅考虑对象和数组两种复杂数据类型
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