C语言近万字为你讲透树与二叉树

C语言近万字为你讲透树与二叉树

什么是树?

树是一种用来组织数据的非线性数据结构,它由一个根节点和若干个子节点组成,并且每个节点可能有若干个子节点。

什么是二叉树?

二叉树是一种特殊的树,它的每个节点最多只有两个子节点,并且分别称为左子节点和右子节点,左子节点在二叉树中永远排在右子节点的前面。

二叉树的遍历方式

二叉树的遍历方式有三种:

  • 前序遍历(preorder traversal):对于每个节点,先访问该节点,然后依次遍历左子树和右子树。
  • 中序遍历(inorder traversal):对于每个节点,先遍历左子树,然后访问该节点,最后遍历右子树。
  • 后序遍历(postorder traversal):对于每个节点,先遍历左子树和右子树,最后访问该节点。

二叉树的实现方式

二叉树的实现可以通过链表或数组来实现,链表实现方式可以采用链式存储结构,数组实现方式可以采用顺序存储结构。

通过链表来实现二叉树

二叉树的节点结构可以定义为:

typedef struct TreeNode {
    int data;
    struct TreeNode *leftChild;
    struct TreeNode *rightChild;
} TreeNode;
  • data:节点的数据,任意数据类型。
  • leftChild:指向该节点的左子树。
  • rightChild:指向该节点的右子树。

通过数组来实现二叉树

数组实现方式可以采用一维数组来存储二叉树,通过计算数组下标来访问相应节点。假设二叉树中的节点按照层级顺序从上至下、从左至右依次编号,那么对于编号为i的节点,

  • 如果i=1,则该节点为树根节点。
  • 如果i>1,则该节点的父节点的编号为i/2(向下取整)。
  • 如果2i≤n,则该节点的左子节点的编号为2i。
  • 如果2i+1≤n,则该节点的右子节点的编号为2i+1。

示例说明

示例1

假设现有以下二叉树:

        5
       / \
      3   7
     / \   \
    1   4   9

该二叉树可以通过链表的方式实现,代码如下:

typedef struct TreeNode {
    int data;
    struct TreeNode *leftChild;
    struct TreeNode *rightChild;
} TreeNode;

void createBinaryTree(TreeNode **root) {
    int data;
    scanf("%d", &data);
    if (data == -1) {
        *root = NULL;
    } else {
        *root = (TreeNode *) malloc(sizeof(TreeNode));
        (*root)->data = data;
        createBinaryTree(&(*root)->leftChild);
        createBinaryTree(&(*root)->rightChild);
    }
}

void preOrderTraversal(TreeNode *root) {
    if (root != NULL) {
        printf("%d ", root->data);
        preOrderTraversal(root->leftChild);
        preOrderTraversal(root->rightChild);
    }
}

void inOrderTraversal(TreeNode *root) {
    if (root != NULL) {
        inOrderTraversal(root->leftChild);
        printf("%d ", root->data);
        inOrderTraversal(root->rightChild);
    }
}

void postOrderTraversal(TreeNode *root) {
    if (root != NULL) {
        postOrderTraversal(root->leftChild);
        postOrderTraversal(root->rightChild);
        printf("%d ", root->data);
    }
}

int main() {
    TreeNode *root = NULL;
    createBinaryTree(&root);
    printf("前序遍历:");
    preOrderTraversal(root);
    printf("\n中序遍历:");
    inOrderTraversal(root);
    printf("\n后序遍历:");
    postOrderTraversal(root);
    printf("\n");
    return 0;
}

在执行该程序时,输入数据为:

5
3
1
-1
-1
4
-1
-1
7
-1
9
-1
-1

程序的输出结果为:

前序遍历:5 3 1 4 7 9
中序遍历:1 3 4 5 7 9
后序遍历:1 4 3 9 7 5

示例2

假设现有以下二叉树:

        5
       / \
      3   7
     / \   \
    1   4   9

该二叉树可以通过数组的方式实现,代码如下:

#define MAX_SIZE 100

int binaryTree[MAX_SIZE] = {5, 3, 7, 1, 4, -1, 9};

void preOrderTraversal(int nodeIndex) {
    if (binaryTree[nodeIndex] != -1) {
        printf("%d ", binaryTree[nodeIndex]);
        preOrderTraversal(2 * nodeIndex);
        preOrderTraversal(2 * nodeIndex + 1);
    }
}

void inOrderTraversal(int nodeIndex) {
    if (binaryTree[nodeIndex] != -1) {
        inOrderTraversal(2 * nodeIndex);
        printf("%d ", binaryTree[nodeIndex]);
        inOrderTraversal(2 * nodeIndex + 1);
    }
}

void postOrderTraversal(int nodeIndex) {
    if (binaryTree[nodeIndex] != -1) {
        postOrderTraversal(2 * nodeIndex);
        postOrderTraversal(2 * nodeIndex + 1);
        printf("%d ", binaryTree[nodeIndex]);
    }
}

int main() {
    printf("前序遍历:");
    preOrderTraversal(1);
    printf("\n中序遍历:");
    inOrderTraversal(1);
    printf("\n后序遍历:");
    postOrderTraversal(1);
    printf("\n");
    return 0;
}

程序的输出结果为:

前序遍历:5 3 1 4 7 9
中序遍历:1 3 4 5 7 9
后序遍历:1 4 3 9 7 5

在程序中,数组binaryTree中按照层级顺序存储了二叉树的所有节点,其中-1表示空节点。可以通过计算数组下标来遍历二叉树。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言近万字为你讲透树与二叉树 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • C++ 数据结构之布隆过滤器

    C++ 数据结构之布隆过滤器 简介 布隆过滤器是一种用于快速判断一个元素是否存在于一个集合中的数据结构。它的空间效率和查询效率都比较高,在某些场景下,它可以代替传统的哈希表。 原理 布隆过滤器的基本原理是:将一个元素映射为多个位数组中的位置。在插入元素时,将这些位置上的值设置为1;在查询元素时,如果这些位置上的值都为1,则认为元素存在于集合中;否则认为元素不…

    数据结构 2023年5月17日
    00
  • C++数据结构与算法之反转链表的方法详解

    C++数据结构与算法之反转链表的方法详解 在C++中,反转链表是一种常见的数据结构与算法技巧。在本文中,我们将详细讲解反转链表的实现过程以及常见的两种反转方法。 基本定义 在开始讲述反转链表算法之前,我们先介绍一下链表的基本定义。 链表是一种数据结构,其中每个节点包含一个数据元素和一个指向下一个节点的指针。下面是一个简单的链表的节点结构定义: struct …

    数据结构 2023年5月17日
    00
  • Java数据结构学习之栈和队列

    Java数据结构学习之栈和队列 什么是栈 栈(stack)是一种线性数据结构,它只能在一端进行插入和删除操作,这一端被称作栈顶(top)。栈的特点是先进后出(FILO,First-In-Last-Out),即最后进入的元素最先被删除。 栈的实现方式 栈可以使用数组或链表来实现。使用数组实现的栈称作顺序栈,使用链表实现的栈称作链式栈。以下是顺序栈的 Java …

    数据结构 2023年5月17日
    00
  • JavaScript数据结构Number

    JavaScript数据结构Number 简介 JavaScript中的Number是一种表示数字的数据类型,包括整数和浮点数。Number类型的值是不可变的。 数字类型(Number)的创建 数字类型可以通过直接赋值的方式创建,如: let num = 10; // 整数 let floatNum = 3.14; // 浮点数 另外,JavaScript还…

    数据结构 2023年5月17日
    00
  • Python实现的数据结构与算法之基本搜索详解

    Python实现的数据结构与算法之基本搜索详解 在计算机科学中,搜索指的是在一组数据中找到目标数据的过程。搜索算法是解决各种问题的关键,即使是拼图游戏和图像识别也要依赖搜索算法。本文将介绍基本的搜索算法,包括线性/顺序搜索、二分搜索和广度优先搜索。 线性/顺序搜索 顺序搜索又称为线性搜索,它遍历整个数据集以查找特定元素。顺序搜索可以用于查找未排序的列表。该算…

    数据结构 2023年5月17日
    00
  • 4种非常实用的python内置数据结构

    下面是关于4种非常实用的Python内置数据结构的详细讲解。 1. List(列表) 列表是Python中最常用的数据结构之一。它可以用来存储有序的数据集合,并且可以通过索引访问其中的元素。 创建列表 要创建一个列表,可以使用方括号[]将元素括起来,用逗号,分隔。例如: fruits = [‘apple’, ‘banana’, ‘orange’] 访问列表元…

    数据结构 2023年5月17日
    00
  • C语言详细分析结构体的内存对齐规则

    C语言详细分析结构体的内存对齐规则 1. 什么是内存对齐 在计算机内存中,每个数据都需要分配一定的内存空间存储,这些空间的大小不一定相同。内存对齐就是要求每个数据按照某个规则,分配其所需的内存空间。 在C语言中,结构体是一种复合数据类型,由多个数据成员组成。结构体的数据成员排列顺序、数据类型均可能不同,因此需要内存对齐来规定内存空间的分配。 2. C语言中结…

    数据结构 2023年5月17日
    00
  • redis中的数据结构和编码详解

    Redis中的数据结构和编码详解 Redis中的数据结构 Redis支持以下五种数据结构: 字符串(string):最基本的数据类型,Redis中的字符串是二进制安全的,意味着您可以在字符串中存储任何数据。例如,您可以将图像文件或序列化对象存储为Redis字符串。字符串最大可以容纳512MB。 列表(list):Redis列表是字符串列表,其中的元素按照插入…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部