一、树的结构定义
一颗树主要包含有节点和数据预,一棵树的某个节点可以有多个节点,所以树的定义可以看成以下:
首先可以先聚焦到树的某个节点,对于树的节点可以包括节点的数据域及指向下一个节点的指针。
typedef struct Node{
int data;
struct Node *next;
}Node, *LinkedList;
根据节点可以定义树的结构,树的结构主要包括树的大小及指向子节点的指针;
typedef struct Tree{
int len;
struct Node *next[i];//当树有多个节点的时候,i的值旧表示有多少个节点
}Node, *Tree;
同时树还有树的高度和度的定义,节点的数量等于边数+1
在树中,最重要的就是二叉树,对于二叉树的定义为:
- 每个节点度最多为2
- 度为0的节点比度为2的节点多一个
二叉树-遍历
对于二叉树的遍历分为三种方法:前序遍历、中序遍历、后序遍历。
前序遍历:先遍历根节点,在遍历左节点,在遍历右节点。
中序遍历:先遍历左节点,在遍历跟节点,后遍历右节点。
后序遍历:先遍历左节点,在遍历右节点,后遍历根节点。
二叉树-完全二叉树
完全二叉树的特点:
- 编号为i的子节点: 左孩子的编号:2i,右孩子的编号:2i + 1
- 有以上性质后,可以用一段连续的空间存储(数组)
以下是二叉树的相关示例代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct Node
{
int data;
struct Node *lchild, *rchild;
}Node;
typedef struct Tree{
Node *root;
int n;
}Tree;
//初始化一个节点
Node *getNewNode(int val){
Node *p = (Node *)malloc(sizeof(Node));
p->data = val;
p->lchild = NULL;
p->rchild = NULL;
return p;
}
//初始化一个树
Tree *getNewTree(){
Tree *T = (Tree *)malloc(sizeof(Tree));
T->root = NULL;
T->n = 0;
return T;
}
//插入一个节点
Node *insertNode(Node *root, int val, int *rev){
if(root == NULL){
*rev = 1;
return getNewNode(val);
}
if(val < root->data) root->lchild = insertNode(root->lchild, val, rev);
else root->rchild = insertNode(root->rchild, val, rev);
return root;
}
void insert(Tree *tree, int val){
int flag = 0;
tree->root = insertNode(tree->root, val, &flag);
tree->n += flag;
return;
}
//释放一个节点
void clear_Node(Node *node){
if(node == NULL) return;
clear_Node(node->lchild);
clear_Node(node->rchild);
free(node);
return;
}
//释放一个数
void clear_tree(Tree *T){
if(T == NULL) return;
clear_Node(T->root);
free(T);
return;
}
void outputNode(Node *root){
if(root == NULL) return;
printf("%d", root->data);
printf("(");
outputNode(root->lchild);
printf(",");
outputNode(root->rchild);
printf(")");
return;
}
//输出一个树
void output(Tree *tree){
printf("tree(%d) = [", tree->n);
outputNode(tree->root);
printf("]\n");
return;
}
//先序遍历
void pre_orderNode(Node *root){
if (root == NULL) return;
printf("%d ", root->data);
pre_orderNode(root->lchild);
pre_orderNode(root->rchild);
}
void pre_order(Tree *tree){
printf("pre_order:");
pre_orderNode(tree->root);
printf("\n");
return;
}
//中序遍历
void in_orderNode(Node *root){
if (root == NULL) return;
in_orderNode(root->lchild);
printf("%d ", root->data);
in_orderNode(root->rchild);
}
void in_order(Tree *tree){
printf("in_order:");
in_orderNode(tree->root);
printf("\n");
return;
}
//后序遍历
void post_orderNode(Node *root){
if (root == NULL) return;
post_orderNode(root->lchild);
post_orderNode(root->rchild);
printf("%d ", root->data);
}
void post_order(Tree *tree){
printf("post_order:");
post_orderNode(tree->root);
printf("\n");
return;
}
int main(void){
srand(time(0));
#define max_op 10
Tree *tree = getNewTree();
for(int i = 0; i < max_op; i++){
int val = rand()%100;
insert(tree, val);
output(tree);
}
pre_order(tree);
in_order(tree);
post_order(tree);
clear_tree(tree);
return 0;
}