力扣133.克隆图

/**
 * Definition for a Node.
 * struct Node {
 *     int val;
 *     int numNeighbors;
 *     struct Node** neighbors;
 * };
 */

#define MAX_NODE_NUM 100
struct Node *cloneGraph(struct Node *s) 
{
    if (s == NULL) {
        return NULL;
    }
    struct Node *vist[MAX_NODE_NUM + 1] = {0}; //存放克隆节点的内存,标记对应节点的内存是否已经申请
    struct Node *que[MAX_NODE_NUM] = {0};
    bool flag[MAX_NODE_NUM + 1] = {0};  //遍历节点时,标记对应节点是否已经处理过
    int head = 0;
    int tail = 0;

    //初始节点入队列
    que[tail++] = s;
    flag[s->val] = true;

    while (head < tail) {
        struct Node *node = que[head++];
        struct Node *clone = NULL;

        //节点内存已申请则直接使用,否则新申请克隆节点内存
        if (vist[node->val]) {
            clone = vist[node->val];
        } else {
            clone = (struct Node *)malloc(sizeof(struct Node));
            memset(clone, 0, sizeof(struct Node));
            vist[node->val] = clone;
        }

        //对节点进行克隆赋值,若邻接指针内存已申请过,直接使用,否则新申请克隆节点的邻接指针内存
        clone->val = node->val;
        clone->numNeighbors = node->numNeighbors;
        if (clone->neighbors == NULL) {
            clone->neighbors = (struct Node **)malloc((clone->numNeighbors) * sizeof(struct Node*));
            memset(clone->neighbors, 0, (clone->numNeighbors) * sizeof(struct Node*));
        }

        //更新克隆节点的邻接指针,如果对应节点的某个邻接指针已申请过,直接更新,否则申请对应邻接点的内存,并更新邻接指针
        int i = 0;
        for (; i < node->numNeighbors; i++) {
            if (vist[node->neighbors[i]->val]) {
                clone->neighbors[i] = vist[node->neighbors[i]->val];
            } else {
                clone->neighbors[i] = (struct Node *)malloc(sizeof(struct Node)); //该节点的克隆赋值将在后面对应节点出队时处理
                memset(clone->neighbors[i], 0, sizeof(struct Node));
                vist[node->neighbors[i]->val] = clone->neighbors[i];
            }
        }

        //遍历当前节点的邻接点,如果对应邻接点没有处理过,则入队,保证每个节点只遍历一次
        for (i = 0; i < node->numNeighbors; i++) {
            if (!flag[node->neighbors[i]->val]) {
                que[tail++] = node->neighbors[i];
                flag[node->neighbors[i]->val] = true;
            }
        }
    }

    return vist[s->val];
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值