王道暑假结构强化应用题打卡表3.2.1-3.3.3

3.2.1

3.3.3

双亲表示法

#include <iostream>
using namespace std;

#define MAXSIZE 100

typedef struct {
    int data;       // 结点数据
    int parent;     // 双亲位置域
} Node;

typedef struct {
    Node nodes[MAXSIZE];  // 结点数组
    int n;          // 结点数
} Tree;

// 初始化树
void InitTree(Tree &T) {
    T.n = 0;
    for(int i = 0; i < MAXSIZE; i++) {
        T.nodes[i].data = -1;
        T.nodes[i].parent = -1;
    }
}

// 添加结点
bool AddNode(Tree &T, int data, int parentPos) {
    if(T.n >= MAXSIZE) {
        cout << "树已满,无法添加新结点!" << endl;
        return false;
    }
    
    T.nodes[T.n].data = data;
    T.nodes[T.n].parent = parentPos;
    T.n++;
    return true;
}

// 查找结点的双亲
int FindParent(Tree T, int pos) {
    if(pos < 0 || pos >= T.n) {
        return -1;
    }
    return T.nodes[pos].parent;
}

// 显示树结构
void DisplayTree(Tree T) {
    cout << "下标\t数据\t双亲位置" << endl;
    cout << "-----------------------" << endl;
    for(int i = 0; i < T.n; i++) {
        cout << i << "\t" << T.nodes[i].data << "\t" << T.nodes[i].parent << endl;
    }
}

// 查找根结点(森林中可能有多个根)
void FindRoots(Tree T) {
    cout << "根结点:";
    bool hasRoot = false;
    for(int i = 0; i < T.n; i++) {
        if(T.nodes[i].parent == -1) {
            cout << "结点" << T.nodes[i].data << "(下标" << i << ") ";
            hasRoot = true;
        }
    }
    if(!hasRoot) {
        cout << "无";
    }
    cout << endl;
}

// 查找结点的孩子
void FindChildren(Tree T, int pos) {
    if(pos < 0 || pos >= T.n) {
        cout << "无效位置!" << endl;
        return;
    }
    
    cout << "结点" << T.nodes[pos].data << "的孩子:";
    bool hasChild = false;
    for(int i = 0; i < T.n; i++) {
        if(T.nodes[i].parent == pos) {
            cout << "结点" << T.nodes[i].data << "(下标" << i << ") ";
            hasChild = true;
        }
    }
    if(!hasChild) {
        cout << "无";
    }
    cout << endl;
}

int main() {
    Tree T;
    InitTree(T);
    
    // 构建一个示例森林(包含两棵树)
    // 第一棵树:A(B(C,D),E)  第二棵树:F(G,H)
    AddNode(T, 1, -1);   // A,根结点,下标0
    AddNode(T, 2, 0);    // B,A的孩子,下标1
    AddNode(T, 3, 1);    // C,B的孩子,下标2
    AddNode(T, 4, 1);    // D,B的孩子,下标3
    AddNode(T, 5, 0);    // E,A的孩子,下标4
    AddNode(T, 6, -1);   // F,根结点,下标5
    AddNode(T, 7, 5);    // G,F的孩子,下标6
    AddNode(T, 8, 5);    // H,F的孩子,下标7
    
    cout << "=== 双亲表示法表示的森林 ===" << endl;
    DisplayTree(T);
    cout << endl;
    
    FindRoots(T);
    cout << endl;
    
    // 测试查找功能
    cout << "=== 结点关系查询 ===" << endl;
    for(int i = 0; i < T.n; i++) {
        int parentPos = FindParent(T, i);
        if(parentPos != -1) {
            cout << "结点" << T.nodes[i].data << "的双亲是结点" 
                 << T.nodes[parentPos].data << endl;
        }
        FindChildren(T, i);
    }
    
    return 0;
}

孩子表示法

#include <iostream>
using namespace std;

typedef struct CNode{
    int data;
    struct CNode *firstChild, *nextSibling;  
}CNode, *CTree;

// 创建新节点
CNode* createNode(int data) {
    CNode* newNode = new CNode;
    newNode->data = data;
    newNode->firstChild = nullptr;
    newNode->nextSibling = nullptr;
    return newNode;
}

// 先根遍历(对应二叉树的先序遍历)
void preOrderTraverse(CTree T) {
    if (T == nullptr) return;
    cout << T->data << " ";
    preOrderTraverse(T->firstChild);
    preOrderTraverse(T->nextSibling);
}

// 后根遍历(对应二叉树的中序遍历)
void postOrderTraverse(CTree T) {
    if (T == nullptr) return;
    postOrderTraverse(T->firstChild);
    cout << T->data << " ";
    postOrderTraverse(T->nextSibling);
}

int main() {
    // 第一棵树:A(B(E,F),C)  第二棵树:D(G,H)
    
    // 创建所有节点
    CNode* A = createNode(1);  // A
    CNode* B = createNode(2);  // B
    CNode* C = createNode(3);  // C
    CNode* D = createNode(4);  // D
    CNode* E = createNode(5);  // E
    CNode* F = createNode(6);  // F
    CNode* G = createNode(7);  // G
    CNode* H = createNode(8);  // H
    
    // 建立第一棵树:A(B(E,F),C)
    A->firstChild = B;     // A的第一个孩子是B
    B->nextSibling = C;    // B的右兄弟是C
    B->firstChild = E;     // B的第一个孩子是E
    E->nextSibling = F;    // E的右兄弟是F
    
    // 建立第二棵树:D(G,H) - 通过D的nextSibling与第一棵树连接形成森林
    C->nextSibling = D;    // C的右兄弟是D(森林中第二棵树的根)
    D->firstChild = G;     // D的第一个孩子是G
    G->nextSibling = H;    // G的右兄弟是H
    
    cout << "先根遍历序列(森林): ";
    preOrderTraverse(A);  // 遍历整个森林
    cout << endl;
    
    cout << "后根遍历序列(森林): ";
    postOrderTraverse(A); // 遍历整个森林
    cout << endl;
    
    // 查找结点B的所有孩子
    cout << "结点B的孩子: ";
    CNode* child = B->firstChild;
    while (child != nullptr) {
        cout << child->data << " ";
        child = child->nextSibling;
    }
    cout << endl;
    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值