day11 树及实现(下)

二叉树的三种遍历

树结构体及数据创建

typedef char data_t; typedef struct node_t { 
    data_t data;             //数据部分 
    struct node_t * left;    //左孩子
     struct node_t * right;  //右孩子 
}bitree;

二叉树的创建

树型结构的创建始于用户的输入相关的,当用户输入的内容没有左子树时,在遍历是需要返回的。

函数原型:

bitree * tree_create();

算法思路:

1、建立根 r (!=#);#代表不存在分支。

2、建立左子树 left;

3,、建立右子树 right。

代码实现:

bitree * tree_ceate() {
    data_t ch;                  //用户输入的数据
    bitree *r;                 //根
    scanf("%c", &ch);
    if(ch == '#')
    return NULL;
    if((r = (bitree *)malloc(sizeof(bitree))) == NULL) {
        printf("malloc failed\n");
        return NULL;
        }
        r->data = ch;
        r->left = tree_create();         //左子树创建
        r->right = tree_create();         //右子树创建
        return r;
}

先序遍历

函数原型:

void preorder(bitree * r);

算法思路:

若二叉树为孔数,则空操作(返回);

否则,

1、访问根节点;

2、先序遍历左子树;

3、先序遍历右子树。

代码实现:

voide preorder(bitree *r) {
    if (r == NULL) {
        return;    
    }
    printf("%c", r->data);
    preorder(r->left);
    preorder(r->right);
}

中序遍历

函数原型:

void inorder(bitree * r);

算法思路:

若二叉树为孔数,则空操作(返回);

否则,

1、先序遍历左子树;

2、访问根节点;

3、先序遍历右子树。

代码实现:

void inorder(bitree * r) {
    if (r == NULL) {
        return;    
    }
    inorder(r->left);
    printf("%c", r->data);
    inorder(r->right);
}

后序遍历

函数原型:

void postorder(bitree * r);

算法思路:

若二叉树为孔数,则空操作(返回);

否则,

1、访问根节点;

2、先序遍历右子树。

3、先序遍历左子树;

代码实现:

voide postorder(bitree * r) {
    if (r == NULL) {
        return;    
    }
    postorder(r->left);
    preorder(r->right);
    postorder("%c", r->data);
}

二叉树的层次遍历

函数原型:

void layerorder(bitree * r);

算法思路:

需要一个链式队列辅助。

1、先访问根节点A,让A入队,A出队判断A是否有左子树,访问左子树B入队,A是否有右子树,有则访问右子树E入队;本层访问结束

2、B出队,判断B是否有左子树,有则访问左子树,没有,则判断是否有右子树,有则访问右子树C入队;

E出队,判断E是否有左子树,无,判断是否有右子树,有,访问右子树F入队;本层访问结束

3、C出队,判断C是否有左子树,有,访问左子树D入队,是否有右子树,无;

判断F是否有左子树,有,访问左子树G入队,是否有右子树,无;本层范根结束;

4、D出队,判断D是否有左右子树,无;

G出队,判断G是否有左子树,有,访问左子树H入队,是否有右子树,有,访问右子树K入队;本层访问结束;

5、H出队,判断H是否有左右子树,无;

K出队,判断K是否有左右子树,无;

二叉树访问结束;

结果为:ABECFDGHK

代码实现:

void layerorder(bitree * r) {
 //创建队列
    linkqueue * lq;
    if ((lq = queue_create()) == NULL)
        return;
    if (r == NULL)
        return;
//访问第一层,入队,
    printf("%c", r->data);
  //访问结束,出队
    enqueue(lq, r);
    while(!queue_empty(lq)) {
            r = dequeue(lq);
            //判断是否有左子树,有则访问入队
            if (r->left) {  
                printf("%c",r->lefet->data);
                //访问结束,出队
                enqueue(lq, r->left);            
            }
            //判断是否有右子树,有则访问入队
            if (r->right) {
                printf("%c", r->right->data);
                //访问结束,出队
                enqueue(lq, r->right);            
            }
    }
    puts("");
        
}

完整代码

tree.h

#ifndef _TREE_H_
#define _TREE_H_

typedef char data_t;

typedef struct node_t {
    data_t data;
    struct node_t * left;
    struct node_t * right;
}bitree;

bitree * tree_create();
void preorder(bitree * r);
void inorder(bitree * r);
void postorder(bitree * r);
void layerorder(bitree * r);

#endif

tree.c


#include <stdio.h>
#include <stdlib.h>
//#include "tree.h"
#include "linkqueue.h"

bitree * tree_create() {
    data_t ch;
    bitree *r;

    scanf("%c", &ch);
    if (ch == '#')
        return NULL;

    if ((r = (bitree *)malloc(sizeof(bitree))) == NULL) {
        printf("malloc failed\n");
        return NULL;
    }
    r->data = ch;
    r->left  = tree_create(); 
    r->right = tree_create(); 
    return r;
}

void preorder(bitree * r) {
    if (r == NULL) {
        return;
    }
    printf("%c", r->data);
    preorder(r->left);
    preorder(r->right);
}

void inorder(bitree * r) {
    if (r == NULL) {
        return;
    }
    inorder(r->left);
    printf("%c", r->data);
    inorder(r->right);
}

void postorder(bitree * r) {
    if (r == NULL) {
        return;
    }
    postorder(r->left);
    postorder(r->right);
    printf("%c", r->data);
}

void layerorder(bitree * r) {
    linkqueue * lq;

    if ((lq = queue_create()) == NULL) 
        return;

    if (r == NULL) 
        return;

    printf("%c", r->data);
    enqueue(lq, r);

    while (!queue_empty(lq)) {
        r = dequeue(lq);
        if (r->left) {
            printf("%c", r->left->data);
            enqueue(lq, r->left);
        }
        if (r->right) {
            printf("%c", r->right->data);
            enqueue(lq, r->right);
        }
    }       
    puts("");
}

linkqueu.h

#include "tree.h"
typedef bitree * datatype;

typedef struct node {
    datatype data;
    struct node *next;
}listnode , *linklist;

typedef struct {
    linklist front;
    linklist rear;
}linkqueue;

linkqueue * queue_create();
int enqueue(linkqueue *lq, datatype x);
datatype dequeue(linkqueue *lq);
int queue_empty(linkqueue *lq);
int queue_clear(linkqueue *lq);
linkqueue * queue_free(linkqueue *lq);

linkqueue.c

#include <stdio.h>
#include <stdlib.h>
#include "tree.h"
#include "linkqueue.h"

linkqueue * queue_create() {
    linkqueue *lq;

    if ((lq = (linkqueue *)malloc(sizeof(linkqueue))) == NULL) {
        printf("malloc linkqueue failed\n");
        return NULL;
    }

    lq->front = lq->rear = (linklist)malloc(sizeof(listnode));
    if (lq->front == NULL) {
        printf("malloc node failed\n");
        return NULL;
    }
    lq->front->data = 0;
    lq->front->next = NULL;

    return lq;
}

int enqueue(linkqueue *lq, datatype x) {
    linklist p;

    if (lq == NULL) {
        printf("lq is NULL\n");
        return -1;
    }

    if ((p = (linklist)malloc(sizeof(listnode))) == NULL) {
        printf("malloc node failed\n");
        return -1;
    }
    p->data = x;
    p->next = NULL;

    lq->rear->next = p;
    lq->rear = p;

    return 0;
}

datatype dequeue(linkqueue *lq) {
    linklist p;

    if (lq == NULL) {
        printf("lq is NULL\n");
        return NULL;
    }

    p = lq->front;
    lq->front = p->next;
    free(p);
    p = NULL;

    return (lq->front->data);
}

int queue_empty(linkqueue *lq) {
    if (lq == NULL) {
        printf("lq is NULL\n");
        return -1;
    }

    return (lq->front == lq->rear ? 1 : 0);
}

int queue_clear(linkqueue *lq) {
    linklist p;

    if (lq == NULL) {
        printf("lq is NULL\n");
        return -1;
    }

    while (lq->front->next) {
        p = lq->front;
        lq->front = p->next;
        //printf("clear free:%d\n", p->data);
        free(p);
        p = NULL;
    }
    return 0;
}

linkqueue * queue_free(linkqueue *lq) {
    linklist p;

    if (lq == NULL) {
        printf("lq is NULL\n");
        return NULL;
    }

    while (lq->front) {
        p = lq->front;
        lq->front = p->next;
        //printf("free:%d\n", p->data);
        free(p);
    }

    free(lq);
    lq = NULL;

    return NULL;
}

main.c

#include <stdio.h>
#include "tree.h"

int main(int argc, const char *argv[])
{
    bitree * r;

    if ((r = tree_create()) == NULL)
        return -1;

    preorder(r);
    puts("");

    inorder(r);
    puts("");

    postorder(r);
    puts("");

    layerorder(r);

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Prim算法是求解最小生成树问题的一种贪心算法,可以使用邻接矩阵来存储图。具体实现步骤如下: 1. 初始化:选择一个起点,将其加入到最小生成树中,将其与其它节点的距离(边权)存入一个数组dist中,将其它节点的前驱节点存入一个数组pre中,将起点的前驱节点设为-1,表示当前点为起点。 2. 重复以下步骤,直到所有节点都被加入到最小生成树中: a. 找到距离最小的未加入节点v,将其加入到最小生成树中。 b. 更新dist和pre数组,将v与其它未加入节点u之间的距离(边权)与dist[u]比较,若小于dist[u],则更新dist[u]和pre[u]。 最终得到的pre数组就是最小生成树的构建过程,代码实现如下: ```c #include <stdio.h> #include <limits.h> #define MAX_VERTICES 100 int graph[MAX_VERTICES][MAX_VERTICES]; // 邻接矩阵表示的图 int dist[MAX_VERTICES]; // 存储节点到最小生成树的距离 int pre[MAX_VERTICES]; // 存储节点的前驱节点 int visited[MAX_VERTICES]; // 标记节点是否已加入到最小生成树中 int prim(int n) // n为节点数 { int i, j; int min_dist, u, v; int total_weight = 0; for (i = 0; i < n; i++) { dist[i] = INT_MAX; pre[i] = -1; visited[i] = 0; } dist[0] = 0; for (i = 0; i < n; i++) { min_dist = INT_MAX; for (j = 0; j < n; j++) { if (!visited[j] && dist[j] < min_dist) { min_dist = dist[j]; u = j; } } visited[u] = 1; total_weight += min_dist; for (v = 0; v < n; v++) { if (!visited[v] && graph[u][v] < dist[v]) { dist[v] = graph[u][v]; pre[v] = u; } } } return total_weight; } int main() { int n, m; int i, j, u, v, w; scanf("%d%d", &n, &m); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { graph[i][j] = INT_MAX; } } for (i = 0; i < m; i++) { scanf("%d%d%d", &u, &v, &w); // 输入边的起点、终点、边权 graph[u][v] = graph[v][u] = w; // 无向图,所以要将两个方向的边都存储 } printf("Total weight of minimum spanning tree: %d\n", prim(n)); return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值