数据结构-树-应用题-5.4-6

已知一棵树的层次序列及每一个结点的度,编写算法构造此树的孩子兄弟链表

设立辅助数组存储新建树各节点的地址。

#define maxNodes 15
void releaseMemory(CSNode* node) {
    if (node) {
        releaseMemory(node->lchild);  // 递归释放孩子节点内存
        releaseMemory(node->rsibling);  // 递归释放兄弟节点内存
        delete node;  // 释放当前节点的内存
    }
}
void creatCSTree(CStree &T,DataType e[],int degree[],int n){
    //e[]层次序列
    CSNode *pointer=new CSNode[maxNodes];
    int i,j,d,k=0;
    for(i=0;i<n;i++){
        pointer[i]->data=e[i];
        pointer[i]->lchild=pointer[i]->rsibling=NUll;
    }
    for(i=0; i<n; i++){
    d = degree[i];  // 获取当前节点i的子节点数(度)
    if(d){  // 如果当前节点有子节点
        k++;  // 移动k到当前节点的第一个子节点的位置
        pointer[i]->lchild = pointer[k];  // 设置当前节点的lchild指向其第一个子节点
        for(j=2; j<=d; j++){  // 遍历除了第一个子节点以外的其他子节点
        //完成了兄弟节点的链接
            k++;  // 移动k到下一个子节点
            pointer[k-1]->rsibling = pointer[k];  // 将当前节点的前一个子节点的rsibling指向当前子节点
        }
    }
}
    T=pointer[0];
    releaseMemory(pointer);
}

### 代码段解析

```c
#define maxNodes 15
```
这行代码定义了一个常量 `maxNodes`,表示树中最大节点数目的上限。这对后续在函数中创建固定大小数组有用。

```c
void creatCSTree(CStree &T, DataType e[], int degree[], int n){
```
定义了函数 `creatCSTree`,接收四个参数:
- `T`:指向 CStree 结构的引用,将作为创建的树的根节点返回。
- `e[]`:层次序列,包含树中节点的数据。
- `degree[]`:每个节点的子节点数(度)。
- `n`:节点总数。

```c
    CSNode *pointer = new CSNode[maxNodes];
```
创建一个动态数组 `pointer`,用于存储所有的树节点。每个节点都是 `CSNode` 类型的。

```c
    int i, j, d, k=0;
```
定义几个整数变量用于控制循环和记录状态:`i` 和 `j` 作为循环计数器,`d` 用于存储当前节点的度数,`k` 用于跟踪当前处理的子节点的索引。

```c
    for(i=0; i<n; i++){
        pointer[i]->data = e[i];
        pointer[i]->lchild = pointer[i]->rsibling = NULL;
    }
```
初始化 `pointer` 数组,为每个节点设置数据和将子节点和兄弟节点指针初始化为 NULL。

```c
    for(i=0; i<n; i++){
        d = degree[i];
        if(d){
            k++;
            pointer[i]->lchild = pointer[k];
            for(j=2; j<=d; j++){
                k++;
                pointer[k-1]->rsibling = pointer[k];
            }
        }
    }
```
对于每个节点,根据其度数 `d`,找到其所有子节点,并适当设置 `lchild` 和 `rsibling` 指针。如果节点有子节点(`d > 0`),则将第一个子节点设置为 `lchild`。随后,用循环连接所有的子节点为一条兄弟链表,使用 `rsibling` 指针。

```c
    T = pointer[0];
```
设置树的根节点为数组中的第一个元素。

for(i=0; i<n; i++){
    d = degree[i];  // 获取当前节点i的子节点数(度)
    if(d){  // 如果当前节点有子节点
        k++;  // 移动k到当前节点的第一个子节点的位置
        pointer[i]->lchild = pointer[k];  // 设置当前节点的lchild指向其第一个子节点
        for(j=2; j<=d; j++){  // 遍历除了第一个子节点以外的其他子节点
            k++;  // 移动k到下一个子节点
            pointer[k-1]->rsibling = pointer[k];  // 将当前节点的前一个子节点的rsibling指向当前子节点
        }
    }
}

这段代码中非常的妙,包含循环和条件逻辑,主要实现以下功能:

  1. 外层循环 (for(i=0; i<n; i++)): 遍历所有的节点,为每个节点配置其子节点的链接。

  2. 获取节点的度 (d = degree[i]): 这告诉我们每个节点有多少个子节点。

  3. 条件判断 (if(d)): 如果节点有一个或多个子节点,则执行内部代码。

  4. 设置第一个子节点 (pointer[i]->lchild = pointer[k]): pointer[i] 是当前正在处理的父节点。它的 lchild 指向由 k 索引的节点,即它的第一个子节点。

  5. 内层循环 (for(j=2; j<=d; j++)): 从第二个子节点开始,直到最后一个子节点。这个循环确保所有子节点之间通过 rsibling 正确连接。在每次循环迭代中,k 自增以指向下一个子节点,并设置前一个子节点的 rsibling 指向当前子节点。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值