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日

相关文章

  • 数据结构 – 绪论

    01.绪论 1. 概念 1.1 数据结构 数据 Data:信息的载体。能被计算机识别并处理的符号的集合。 数据元素 Data element:数据的基本单位,通常作为一个整体进行考虑和处理。一个数据元素往往由若干数据项组成。数据项是组成数据元素的不可分割的最小单位。 如学生的信息记录就是一个数据元素,它由学号、姓名、性别等组成。 数据对象 Data obje…

    算法与数据结构 2023年4月18日
    00
  • Java二叉树查询原理深入分析讲解

    Java二叉树查询原理深入分析讲解 什么是二叉树? 二叉树是一种数据结构,它由节点和边组成,其中每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树的节点是按照一定顺序排列的,这个顺序被称为遍历顺序。通常,我们使用前序遍历、中序遍历和后序遍历三种方法来遍历二叉树。 二叉树的查询 二叉树的查询是指在二叉树中查找包含特定数据的节点。通常,我们使用递归算法…

    数据结构 2023年5月17日
    00
  • Java实题演练二叉搜索树与双向链表分析

    Java实题演练二叉搜索树与双向链表分析 题目描述 给定一个二叉搜索树,将它转换成一个排序的双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。 思路分析 对于一颗二叉搜索树,有以下性质: 若左子树不为空,则左子树上所有结点的值均小于它的根结点的值; 若右子树不为空,则右子树上所有结点的值均大于它的根结点的值; 左右子树也为二叉搜索树。 我们考虑…

    数据结构 2023年5月17日
    00
  • java实现队列数据结构代码详解

    Java实现队列数据结构代码详解 1. 队列数据结构简介 队列(Queue)是一种先进先出(FIFO)的数据结构,支持在一端插入元素,在另一端删除元素并返回删除的元素。其操作包括入队(enqueue)和出队(dequeue)。 2. 队列实现方法 队列可以通过数组或链表来实现。其中,数组实现的队列称为顺序队列,链表实现的队列称为链式队列。 2.1 顺序队列 …

    数据结构 2023年5月17日
    00
  • 一起来看看C语言线性表的线性链表

    一起来看看C语言线性表的线性链表攻略 线性链表概述 线性链表是线性表的一种实现方式,它通过每个节点中包含指向下一个节点的指针来实现表中元素之间的链接,可以动态地增加、删除节点。线性链表分为带头节点的链表和不带头节点的链表,其中带头节点的链表更为常见。 实现思路 结构体定义 我们可以定义一个结构体来表示每个节点,例如: typedef struct ListN…

    数据结构 2023年5月17日
    00
  • C语言数据结构与算法时间空间复杂度基础实践

    C语言数据结构与算法时间空间复杂度基础实践攻略 基本概念 时间复杂度:算法在执行时所需要的基本操作数,通常用O(n)表示,其中n是输入数据的规模。时间复杂度越小,算法执行所需要的时间越少,算法效率越高。 空间复杂度:算法在执行时所需要的额外空间数,通常用O(S)表示,其中S是额外的空间数。空间复杂度越小,所需的额外空间越少,算法的内存效率越高。 实践步骤 1…

    数据结构 2023年5月17日
    00
  • Java 超详细图解集合框架的数据结构

    下面是完整攻略: Java 超详细图解集合框架的数据结构 简介 集合框架是Java中最基础的数据结构之一,是大部分Java程序员必须掌握的基础知识。这个框架提供了常用的数据结构和算法,包括List、Set、Map等等。本文将带领您从数据结构的角度详细解析Java集合框架中的各种数据结构,让您能够清晰地掌握它们的特点和使用方法。 数据结构 Java集合框架中的…

    数据结构 2023年5月17日
    00
  • Python数据结构之双向链表详解

    Python数据结构之双向链表详解 什么是双向链表? 在计算机科学中,双向链表是链表的一种,每个结点除了储存下一个结点的指针外,还储存着前一个结点的指针。这个“前进”指针被称为“ next指针”,而“后退”指针被称为“previous指针”。 双向链表和单向链表的区别在于,单向链表的每个结点只储存一个指向下一个结点的指针,而双向链表储存了前一个和后一个结点的…

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