1.先创建tree.h声明文件( Linux 命令:touch tree.h)。编写函数声明如下(打开文件 Linux 操作命令:vim tree.h):
//树的头文件位置
#ifndef __TREE_H__
#define __TREE_H__
//节点
typedef struct node{
int data;//数据
struct node* left;//记录左侧子节点地址
struct node* right;//记录右侧子节点地址
}node_t;
//树
typedef struct tree{
node_t* root;//记录树根的地址
int cnt;//节点个数
}tree_t;
//树的操作
//树的初始化
//tree_t tree; tree.root tree.cnt
void treeInit(tree_t* t);
//插入节点
void treeInsert(tree_t* t,int data);
//删除节点
void treeDel(tree_t* t,int data);
//前序遍历
void treeFirst(node_t* n);
//中序遍历
void treeMid(node_t* n);
//后序遍历
void treeLast(node_t* n);
#endif //__TREE_H__
2.创建函数实现文件tree.c( Linux 命令:touch tree.c)。写入函数到文件中:
//树的实现
#include<stdio.h>
#include<stdlib.h>
#include"tree.h"
//树的初始化
//tree_t tree;
//treeinit(&tree);
void treeInit(tree_t* t){
t->root=NULL;
t->cnt=0;
}
//树的插入
void treeInsert(tree_t* t){
//创建新节点
node_t* new=malloc(sizeof(node_t));
new->data=data;
new->left=NULL;
new->right=NULL;
//找位置插入
//如果root位NULL,说明没有树根,此次新节点应该作为树根
if(t->root==NULL){
t->root=new;
t->cnt++
return;
}
// 通过p1 p2确定具体的插入位置
node_t* p1,*p2;
p1=p2=t->root;
while(p2!=NULL){
//p1慢p2一步
p1=p2;
if(p2->data>data){
p2=p2->left;
}else if(p2->data<data){
p2=p2->right;
}else{
printf("节点存在!\n");
free(new);//释放新节点的存储区!
return;
}
}//循环结束时,p2指向NULL,p1指向的节点就是新节点的父节点
//判断新节点在p1指向节点的哪侧
if(p1->data>data){
// 新节点在左侧
p1->left=new;
}else{
// 新节点在右侧
p1->right=new;
}
//计数加一
t->cnt++;
}
//删除节点
void treeDel(tree_t* t,int data){
//找到要删除的节点
node_t* pp =t->root;//要删除节点的父节点
node_t* pc =t->root;//要删除的节点
while(pc!=NULL&&pc->data!=data){//判空条件要放前面,否则pc为空时会段错误
//pp慢pc一步
pp=pc;
//pc继续向下找
if(pc->data>data){
//向左找
pc=pc->left;
}else{
//向右找
pc=pc->right;
}
}//循环结束时,pc要么指向要删除的节点,要么指向NULL
//pp指向要删除节点的父节点
if(pc==NULL){
printf("节点不存在!\n");
return;
}
//根据节点情况进行删除
node_t* left=pc->left;//表示要删除节点的左子树
node_t* right=pc->right;//表示删除节点的右子树
// 说明要删除的节点,左右子树都没有
if(left==NULL&&right==NULL){
if(pc->data>pp->data){
//目标节点在父节点右侧
pp->right=NULL;
}else{
pp->left=NULL;
}
//释放目标节点
free(pc);
//计数减一
t->cnt--;
}
//没有左子树 有右子树
if(left==NULL&&right!=NULL){
//将右子树,挂在父节点上
if(pc->data>pp->data){
//右子树,挂在父节点的右侧
pp->right=right;
}else{
//左侧
pp->left=right;
}
//释放目标节点
free(pc);
//计数减一
t->cnt--;
}
//没有右子树 有左子树
if(left==NULL&&right!=NULL){
//将右子树,挂在父节点上
if(pc->data>pp->data){
//右子树,挂在父节点的右侧
pp->right=left;
}else{
//左侧
pp->left=left;
}
//释放目标节点
free(pc);
//计数减一
t->cnt--;
}
}
3.编写主函数调用文件main.c(Linux命令:touch main.c)。编写逻辑操作:
#include<stdio.h>
#include"tree.h"
int main(void){
//树
tree_t tree;
//初始化
treeInit(&tree);
//插入节点
treeInsert(&tree,60);
treeInsert(&tree,30);
treeInsert(&tree,90);
treeInsert(&tree,10);
treeInsert(&tree,50);
treeInsert(&tree,20);
treeInsert(&tree,40);
treeInsert(&tree,80);
treeInsert(&tree,100);
treeInsert(&tree,70);
treeFirst(tree.root);
printf("\n");
treeMid(tree.root);
printf("\n");
treeLast(tree.root);
printf("\n");
treeDel(&tree,30);
treeFirst(tree.root);
printf("\n");
treeMid(tree.root);
printf("\n");
treeLast(tree.root);
printf("\n");
return 0;
}
4.编译运行
Linux命令:gcc main.c tree.c -o tree
运行:./tree