二叉树的存储

二叉树的顺序存储:

即将二叉树中的结点所存数据从上到下从左自右依次存入一个数组中,当某个结点无左孩子或右孩子则在数组中存入0随后继续往后存储

注:(但是这种方法平常却并不常见因为会有大量的空间浪费,一般用于存储完全二叉树)

#include <stdio.h>  
#include <stdlib.h>  

#define MAX_SIZE 100 // 假设数组的最大大小  

// 函数声明  
void preorderTraversal(int arr[], int start, int end);

int main() {
    // 示例:使用数组表示一个完全二叉树  
    //        1  
    //       / \  
    //      2   3  
    //     / \  
    //    4   5  
    //   /  
    //  6  
    int tree[MAX_SIZE] = { 1, 2, 3, 4, 5, 6, 0, 0, 0, 0 }; // 0 表示空结点  

    // 注意:我们需要知道树中实际有多少个结点,但这里为了简化,我们假设数组已满或我们知道最后一个非零元素的位置  
    // 在实际应用中,你可能需要额外的信息来跟踪树的大小  

    // 前序遍历输出  
    printf("前序排列为: ");
    preorderTraversal(tree, 0, MAX_SIZE - 1); // 假设我们遍历整个数组,但实际上应该只遍历到最后一个非空结点  
    printf("\n");

    return 0;
}

// 前序遍历函数,但这里需要额外的逻辑来处理数组中的空结点  
void preorderTraversal(int arr[], int start, int end) {
    if (start > end) { // 递归的基本情况:如果当前索引超出了数组范围,则返回  
        return;
    }

    if (arr[start] != 0) { // 检查当前结点是否非空  
        printf("%d ", arr[start]); // 访问结点  

        // 计算左子结点的索引  
        int left = 2 * start + 1;
        // 计算右子结点的索引  
        int right = 2 * start + 2;

        // 递归遍历左子树  
        preorderTraversal(arr, left, end);
        // 递归遍历右子树  
        preorderTraversal(arr, right, end);
    }
    else {
        // 如果当前结点为空,则跳过它(这实际上在完全二叉树中是不必要的,但在非完全二叉树中可能是必要的)  
        // 但由于我们假设这是一个完全二叉树,并且数组是紧密填充的(除了尾部可能有一些0),所以这里的else分支实际上不会被执行  
        // 然而,为了完整性,我还是包含了它  
        // 注意:在非完全二叉树的情况下,你可能需要在这里添加额外的逻辑来跳过整个子树  
    }
}

二叉树的链式存储

定义一个结构体使每一个结点的数据类型都包含两个指针域一个指向左孩子,一个指向右孩子,还有一个存储当前的值的数据域,再采用递归的方式,其指向的左右孩子同样含有上述的属性,一直递归下去直到将所有元素都存储完。

#include <stdio.h>  
#include <stdlib.h>  

// 定义二叉树节点结构体  
typedef struct TreeNode {
    int data;
    struct TreeNode* left;
    struct TreeNode* right;
} TreeNode;

// 函数声明  
TreeNode* createNode(int data);
void preorderTraversal(TreeNode* root);
void  middleTraversal(TreeNode* root);
void laterTraversal(TreeNode* root);

int main() {
    // 创建二叉树  
    //       1  
    //      / \  
    //     2   3  
    //    / \  
    //   4   5  
    TreeNode* root = createNode(1);
    root->left = createNode(2);
    root->right = createNode(3);
    root->left->left = createNode(4);
    root->left->right = createNode(5);

    // 前序遍历  
    printf("前序遍历为: ");
    preorderTraversal(root);
    printf("\n");

    printf("中序遍历为: ");
    middleTraversal(root);
    printf("\n");

    printf("后序遍历为: ");
    laterTraversal(root);
    printf("\n");

    return 0;
}

// 创建新节点  
TreeNode* createNode(int data) {
    TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));
    if (!newNode) {
        printf("分配存储空间失败\n");
        exit(1);  //当malloc函数分配空间失败则,结束该程序执行
    }
    newNode->data = data;
    newNode->left = NULL;
    newNode->right = NULL;
    return newNode; //结束该函数并返回newNode
}

// 前序遍历函数  
void preorderTraversal(TreeNode* root) {
    if (root == NULL) {
        return;
    }
    printf("%d ", root->data); // 访问根节点  
    preorderTraversal(root->left); // 遍历左子树  
    preorderTraversal(root->right); // 遍历右子树  
}

// 中序遍历函数  
void middleTraversal(TreeNode* root) {
    if (root == NULL) {
        return;
    }
   
    middleTraversal(root->left); // 遍历左子树  
    printf("%d ", root->data); // 访问根节点  
    middleTraversal(root->right); // 遍历右子树  
}

// 后序遍历函数  
void laterTraversal(TreeNode* root) {
    if (root == NULL) {
        return;
    }

    laterTraversal(root->left); // 遍历左子树  
    laterTraversal(root->right); // 遍历右子树  
    printf("%d ", root->data); // 访问根节点  
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值