广度优先遍历代码

本文介绍了一种使用队列实现的二叉树广度优先遍历算法(层序遍历),并提供了完整的C语言实现代码。该算法自上而下、从左到右逐层遍历二叉树,适用于多种应用场景。
广度优先周游二叉树(层序遍历)是用队列来实现的,从二叉树的第一层(根结点)开始,自上至下逐层遍历;在同一层中,按照从左到右的顺序对结点逐一访问。
按照从根结点至叶结点、从左子树至右子树的次序访问二叉树的结点。算法:
    1初始化一个队列,并把根结点入列;
    2根节点入队
    3循环直到队列空
      3.1  q=队列头元素出队
      3.2  访问q的数据域
      3.3  若q有左孩子  左孩子入队
      3.4  若q有右孩子  右孩子入队

代码来自 http://leidiqiu.iteye.com/blog/854087  

 
  #include <stdio.h>  
    #include <stdlib.h>  
      
    //树节点的定义  
    struct TNode{  
        int value;  
        struct TNode *left;  
        struct TNode *right;  
    };  
      
    //队列节点的定义  
    struct QNode{  
        struct TNode *p;  
        struct QNode *next;  
    };  
      
    //队列的定义  
    struct Queue{  
        struct QNode *front;  
        struct QNode *rear;  
    };  
      
    //初始化队列  
    void InitQueue(struct Queue *Q){  
        Q->front=Q->rear=(struct QNode*)malloc(sizeof(struct QNode));  
        Q->front->next=NULL;  
    }  
      
    //入队列  
    void EnQueue(struct Queue *Q, struct TNode *node){  
        printf("en-node-value:%d\n",node->value);  
        struct QNode *nd=(struct QNode*)malloc(sizeof(struct QNode));  
        nd->next=NULL;  
        nd->p=node;  
        Q->rear->next=nd;  
        Q->rear=nd;  
    }  
      
    //出队列,注意判定快为空时,应有 rear=front  
    struct TNode* DeQueue(struct Queue *Q){  
        struct QNode *p=Q->front->next;  
        Q->front->next=Q->front->next->next;  
        struct TNode *t=p->p;  
        if(Q->rear==p){  
            Q->rear=Q->front;  
        }  
        free(p);  
        printf("de-node-value:%d\n",t->value);  
        return t;  
    }  
      
    //建立二叉树  
    void createLR(struct TNode *node){  
        if(node->value<20){  
            struct TNode *n1=(struct TNode*)malloc(sizeof(struct TNode));  
            struct TNode *n2=(struct TNode*)malloc(sizeof(struct TNode));  
            node->left=n1;  
            n1->value=node->value*2;  
            node->right=n2;  
            n2->value=node->value*2+1;      
            createLR(n1);  
            createLR(n2);  
        }else{  
            node->left=NULL;  
            node->right=NULL;  
        }  
    }  
      
    //主程序  
    int main(int argc, char **argv){  
      
        struct TNode *head=(struct TNode*)malloc(sizeof(struct TNode));  
        head->value=1;  
        createLR(head);  
      
                    //输出左、右边,测试树是否正确建立  
        struct TNode *p=head;  
        while(p){  
            printf("%d\n",p->value);  
            p=p->left;  
        }  
        p=head;  
        while(p){  
            printf("%d\n",p->value);  
            p=p->right;  
        }  
        printf("\n");  
      
                    //用一个辅助的链队列,广度遍历树  
        p=head;  
        struct Queue *q;  
        InitQueue(q);  
        printf("%d\n",p->value);  
        EnQueue(q,p);  
        while(q->front->next!=NULL){  
            p=DeQueue(q);  
            if(p->left!=NULL){  
                printf("%d\n",p->left->value);  
                EnQueue(q,p->left);  
            }  
            if(p->right!=NULL){  
                printf("%d\n",p->right->value);  
                EnQueue(q,p->right);  
            }  
        }  
          
                    //以下代码没有别的意思,就是测试命令行参数  
        int i=0;  
        for(i=0; i<argc; i++){  
            printf("%s\n",argv[i]);  
        }  
      
        return 0;  
    }  

### 深度优先遍历 (DFS) 的代码实现 以下是深度优先遍历的递归和非递归两种实现方式。 #### 递归实现 ```c void DFS(Graph G, int v) { visit(v); // 访问顶点v visited[v] = true; // 标记顶点v为已访问 for (int w = FirstAdjVex(G, v); w >= 0; w = NextAdjVex(G, v, w)) { // 遍历v的所有邻接点 if (!visited[w]) { // 如果邻接点未被访问 DFS(G, w); // 递归调用DFS } } } ``` 上述代码中,`FirstAdjVex` 和 `NextAdjVex` 分别用于获取顶点的第一个邻接点和下一个邻接点[^1]。 #### 非递归实现 非递归实现使用栈来模拟递归过程。 ```c void DFS_Iterative(Graph G, int v) { Stack S; initStack(&S); push(&S, v); visited[v] = true; // 标记起始顶点为已访问 while (!isEmpty(&S)) { int u = pop(&S); // 弹出栈顶元素 visit(u); // 访问该顶点 for (int w = FirstAdjVex(G, u); w >= 0; w = NextAdjVex(G, u, w)) { // 遍历u的所有邻接点 if (!visited[w]) { // 如果邻接点未被访问 push(&S, w); // 将邻接点压入栈中 visited[w] = true; // 标记为已访问 } } } } ``` 在非递归实现中,栈的作用是保存当前路径上的节点以便后续回溯[^2]。 --- ### 广度优先遍历 (BFS) 的代码实现 广度优先遍历通常使用队列来实现,确保先访问离起点更近的节点。 ```c void BFS(Graph G, int v) { Queue Q; initQueue(&Q); enqueue(&Q, v); visited[v] = true; // 标记起始顶点为已访问 while (!isEmpty(&Q)) { int u = dequeue(&Q); // 弹出队首元素 visit(u); // 访问该顶点 for (int w = FirstAdjVex(G, u); w >= 0; w = NextAdjVex(G, u, w)) { // 遍历u的所有邻接点 if (!visited[w]) { // 如果邻接点未被访问 enqueue(&Q, w); // 将邻接点加入队列 visited[w] = true; // 标记为已访问 } } } } ``` 上述代码中,队列的作用是按层次存储待访问的节点,确保同一层的节点在下一层之前被访问[^3]。 --- ### 总结 - 深度优先遍历可以通过递归或非递归方式实现,递归实现更为简洁,而非递归实现则通过显式栈模拟递归过程。 - 广度优先遍历必须使用队列,以保证节点按层次访问。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值