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日

相关文章

  • Java数据结构及算法实例:插入排序 Insertion Sort

    Java数据结构及算法实例:插入排序 Insertion Sort 算法简介 插入排序是一种简单的排序算法,它的工作方式是每次将一个待排序的元素与前面已经排好序的元素逐个比较,并插入到合适的位置。插入排序的时间复杂度为O(n^2),是一种比较低效的排序算法。 算法实现 以下是使用Java语言实现插入排序算法的代码: public static void in…

    数据结构 2023年5月17日
    00
  • C#模拟链表数据结构的实例解析

    C#模拟链表数据结构的实例解析 简介 链表是一种常见的数据结构,它由一系列节点组成,每个节点包含一个数据元素和指向下一个节点的指针。本篇文章将介绍如何使用 C# 来模拟链表数据结构,并通过两个示例展示如何实现链表的操作。 链表的基本结构 链表是由一系列节点组成的,每个节点包含一个数据元素和指向下一个节点的指针。我们可以通过以下代码定义一个链表节点的类: pu…

    数据结构 2023年5月17日
    00
  • 详解python数据结构之栈stack

    详解Python数据结构之栈stack 什么是栈stack 栈是一种先进后出(LIFO)的数据结构,只允许在表的一端进行插入和删除操作。栈的入口称为栈底,出口称为栈顶。栈常用于表达式求值、函数调用等场景。 栈的操作 栈的基本操作包括入栈(push)和出栈(pop)。其他常用的操作有判断栈是否为空(isEmpty)、获取栈的大小(size)和获取栈顶元素(pe…

    数据结构 2023年5月17日
    00
  • Java 超详细讲解数据结构的应用

    Java 超详细讲解数据结构的应用 简介 “Java 超详细讲解数据结构的应用”是一个基于Java语言的数据结构教程,其中包含了各种数据结构的理论知识和实际应用,在学习过程中可以帮助初学者更好地理解数据结构的本质和实际应用场景。 学习路径 数据结构理论 在本教程中,我们首先介绍了数据结构的几种基本分类和常用的数据结构,包括数组、链表、栈、队列、堆、树、图等等…

    数据结构 2023年5月17日
    00
  • 线段树好题! P2824 [HEOI2016/TJOI2016]排序 题解

    题目传送门 前言 线段树好题!!!!咕咕了挺久的一道题目,很早之前就想写了,今天终于找了个时间A掉了。 题意 给定一个 \(1\) 到 \(n\) 的排列,有 \(m\) 次操作,分两种类型。1.0 l r表示将下标在 \([l, r]\) 区间中的数升序排序。2.1 l r表示将下标在 \([l, r]\) 区间中的数降序排序。给定一个数 \(q\) 询问…

    算法与数据结构 2023年4月17日
    00
  • mosn基于延迟负载均衡算法 — 走得更快,期待走得更稳

    前言 这篇文章主要是介绍mosn在v1.5.0中新引入的基于延迟的负载均衡算法。 对分布式系统中延迟出现的原因进行剖析 介绍mosn都通过哪些方法来降低延迟 构建来与生产环境性能分布相近的测试用例来对算法进行验证 地址:https://github.com/mosn/mosn/pull/2253 在开始聊基于延迟的负载均衡算法之前,先介绍下什么是负载均衡——…

    算法与数据结构 2023年5月8日
    00
  • Java数据结构之LinkedList的用法详解

    Java数据结构之LinkedList的用法详解 LinkedList简介 LinkedList是Java中的一个数据结构,它是一个双向链表,可以提供快速的插入和删除操作。LinkedList中的元素分别保存在每个节点中,每个节点包含了指向前一个节点和后一个节点的引用。 使用LinkedList的好处是,其可以快速的进行插入和删除操作,但是如果需要随机存取中…

    数据结构 2023年5月17日
    00
  • JavaScript数据结构之广义表的定义与表示方法详解

    JavaScript数据结构之广义表的定义与表示方法详解 什么是广义表 广义表是一种包含了无数元素的数据结构,可以是元素或者嵌套的子表。广义表可以表示为: $\quad\quad\quad GL = (a_0,a_1,…,a_n)$ 其中$a_i$可以是元素或者一个子表,如果$a_i$为一个子表,那么$a_i$本身也是一个广义表。广义表中,第一个元素$a…

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