C语言数据结构-树


树是一些节点的集合,可以是空集也可以不是,树的最开始节点为根,其它的为儿子,一个节点可以有多个儿子也可以没有。
1、结点的度
  树中的一个结点拥有的子树数称为该结点的度;一棵树的度是指该树中结点的最大度数。度为零的结点称为叶子(Leaf)或终端结点。度不为零的结点称分支结点或非
2、路径
  若树中存在一个结点序列k1,k2,…,ki,使得ki是ki+1的双亲,则称该结点序列是从kl到kj的一条路径,路径的长度指路径所经过的边(即连接两个结点的线段)的数目。
3、节点的深度
 结点的深度为根到节点路径的长,根的深度为1,其余结点的深度等于其双亲结点的深度加1。树中结点的最大深度称为树的高度(Height)或深度(Depth)。

二叉树
二叉树是一种比较特殊的数型结构,它的每个节点最多只能有两个子节点。如下图:

这里写图片描述

二叉树的存储:
这里只介绍二叉树的链式存储结构,其每个节点结构有一个数据,一个指向左子节点的指针和一个指向右子节点的指针;
具体如下图:

这里写图片描述

满二叉树
  一棵深度为k且有2^k-1个结点的二又树称为满二叉树。
  满二叉树的特点:
  (1) 每一层上的结点数都达到最大值。即对给定的高度,它是具有最多结点数的二叉树。
  (2) 满二叉树中不存在度数为1的结点,每个分支结点均有两棵高度相同的子树,且树叶都在最下一层上。
  
完全二叉树
  若一棵二叉树至多只有最下面的两层上结点的度数可以小于2,并且最下一层上的结点都集中在该层最左边的若干位置上,则此二叉树称为完全二叉树。
  特点:
  (1) 满二叉树是完全二叉树,完全二叉树不一定是满二叉树。
  (2) 在满二叉树的最下一层上,从最右边开始连续删去若干结点后得到的二叉树仍然是一棵完全二叉树。
  (3) 在完全二叉树中,若某个结点没有左孩子,则它一定没有右孩子,即该结点必是叶结点。
  
二叉树的遍历:
  二叉树主要有三种遍历方式(由根节点遍历的顺序来决定是哪一种遍历方式,左节点始终在右节点之前):
1.中序遍历
若二叉树非空,则依次执行如下操作:
(1)遍历左子树;
(2)访问根结点;
(3)遍历右子树。

2.先序遍历
若二叉树非空,则依次执行如下操作:
(1) 访问根结点;
(2) 遍历左子树;
(3)遍历右子树。

3.后序遍历
若二叉树非空,则依次执行如下操作:
(1)遍历左子树;
(2)遍历右子树;
(3)访问根结点。
下面通过程序实现二叉树的定义和相关一些运算:
有关二叉树的各种运算基本都利用了递归函数,队二叉树进行分层运算;

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

#define DataType int

//二叉树结点构造
typedef struct node
{
    DataType data;
    struct node *lchild;
    struct node *rchild;
}BinNode;
typedef BinNode *BinTree;

//二叉树遍历(先序)
void TreeTraversal1(BinTree T)
{
    if(T)
    {
        printf("%d\t",T->data);  //  输出节点值
        TreeTraversal1(T->lchild);      // 遍历左子节点
        TreeTraversal1(T->rchild);          //遍历右子节点
    }
}

//二叉树遍历(中序)
void TreeTraversal2(BinTree T)
{
    if(T)
    {
        TreeTraversal2(T->lchild);      
  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: (Tree)是一种非线性的数据结构,它由n(n>=0)个结点构成,其中一个结点为根结点,其余结点可分为m(m>=0)个互不相交的子集T1、T2、……、Tm,其中每一个子集本身又是一棵,并称为根的子的特点是:每个结点有零个或多个子结点;没有父结点结点称为根结点;每一个非根结点有且只有一个父结点;除了根结点之外,每个子结点可以分为多个不相交的子。 下面是一个基本的的结构定义: ```c // 的结构体定义 typedef struct TreeNode { int data; // 数据域 struct TreeNode *firstChild;// 第一个子节点 struct TreeNode *nextSibling;// 兄弟节点 }TreeNode, *Tree; ``` 其中,data表示结点的数据域,firstChild指向该结点的第一个子节点,nextSibling指向该结点的下一个兄弟节点。 下面是一个创建的函数: ```c // 创建 Tree createTree(int data) { Tree root = (Tree)malloc(sizeof(TreeNode)); root->data = data; root->firstChild = NULL; root->nextSibling = NULL; return root; } ``` 下面是一个向中添加子节点的函数: ```c // 添加子节点 void addChild(Tree parent, int data) { Tree child = (Tree)malloc(sizeof(TreeNode)); child->data = data; child->firstChild = NULL; child->nextSibling = NULL; if (parent->firstChild == NULL) parent->firstChild = child; else { Tree p = parent->firstChild; while (p->nextSibling != NULL) p = p->nextSibling; p->nextSibling = child; } } ``` 下面是一个先序遍历的函数: ```c // 先序遍历 void preOrderTraversal(Tree root) { if (root != NULL) { printf("%d ", root->data); preOrderTraversal(root->firstChild); preOrderTraversal(root->nextSibling); } } ``` 下面是一个后序遍历的函数: ```c // 后序遍历 void postOrderTraversal(Tree root) { if (root != NULL) { postOrderTraversal(root->firstChild); postOrderTraversal(root->nextSibling); printf("%d ", root->data); } } ``` 下面是一个层次遍历的函数: ```c // 层次遍历 void levelOrderTraversal(Tree root) { Queue q; initQueue(&q); if (root != NULL) { enQueue(&q, root); while (!isQueueEmpty(&q)) { Tree p = deQueue(&q); printf("%d ", p->data); if (p->firstChild != NULL) enQueue(&q, p->firstChild); if (p->nextSibling != NULL) enQueue(&q, p->nextSibling); } } } ``` 其中,Queue是一个队列结构体。 以上就是一个简单的的实现。 ### 回答2: 是一种常见的数据结构,用于存储具有层次关系的数据。它由节点和边组成,通常包含一个根节点和若干子节点。 在C语言中,我们可以使用结构体来定义的节点。一个最基本的节点结构体可能包含两个成员变量:数据和指向子节点的指针。例如: ``` typedef struct TreeNode { int data; struct TreeNode* left; struct TreeNode* right; } TreeNode; ``` 上述代码定义了一个名为TreeNode的结构体,它包含一个整型数据成员和两个指向左子节点和右子节点的指针。 为了方便操作,我们可以定义一些基本的函数。其中,创建节点的函数可以使用动态内存分配来分配新节点的内存空间。例如: ``` TreeNode* createNode(int data) { TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode)); newNode->data = data; newNode->left = NULL; newNode->right = NULL; return newNode; } ``` 我们还可以定义插入节点、删除节点、搜索节点等函数来操作的结构。 除此之外,还可以实现一些遍历的算法,如先序遍历、中序遍历和后序遍历。这些遍历方法可以递归地遍历的节点,并对节点进行指定的操作。 编写的操作函数时,需要考虑到不同的特点,例如二叉搜索要保持左子节点的值小于根节点,右子节点的值大于根节点。 总之,编写一个经典C语言数据结构-需要定义节点的结构体,实现节点的创建、插入、删除和搜索等操作函数,同时可以实现遍历的算法。 ### 回答3: 是一种经典的数据结构C语言可以很方便地实现的相关操作。首先,我们可以定义一个的节点结构体: ```c typedef struct Node { int data; // 节点存储的数据 struct Node* left; // 左子指针 struct Node* right; // 右子指针 } Node; ``` 接下来,我们可以实现一些的基本操作,例如创建、插入节点、删除节点和遍历。下面是一个简单的示例: ```c // 创建一个节点 Node* createNode(int data) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = data; newNode->left = NULL; newNode->right = NULL; return newNode; } // 在中插入一个节点 Node* insertNode(Node* root, int data) { if (root == NULL) { return createNode(data); } else if (data < root->data) { root->left = insertNode(root->left, data); } else if (data > root->data) { root->right = insertNode(root->right, data); } return root; } // 在中删除一个节点 Node* deleteNode(Node* root, int data) { if (root == NULL) { return root; } else if (data < root->data) { root->left = deleteNode(root->left, data); } else if (data > root->data) { root->right = deleteNode(root->right, data); } else { if (root->left == NULL) { Node* temp = root->right; free(root); return temp; } else if (root->right == NULL) { Node* temp = root->left; free(root); return temp; } Node* temp = findMinNode(root->right); root->data = temp->data; root->right = deleteNode(root->right, temp->data); } return root; } // 遍历:前序遍历(中-左-右) void preOrderTraversal(Node* root) { if (root != NULL) { printf("%d ", root->data); preOrderTraversal(root->left); preOrderTraversal(root->right); } } ``` 这只是的基本实现,还有很多其他操作,例如查找节点、判断是否为空、计算的高等。可以根据具体需求进行扩展。通过以上实现,我们可以使用经典的C语言来构建和操作结构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值