有序二叉树各种操作实现(数据结构C语言多文件编写)

1. 先创建tree.h声明文件( Linux 命令:touch tree.h)。编写函数声明如下(打开文件 Linux 操作命令:vim tree.h):

cpp 复制代码
//树的头文件位置
#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)。写入函数到文件中:

cpp 复制代码
//树的实现
#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)。编写逻辑操作:

cpp 复制代码
#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

相关推荐
Morwit4 分钟前
【力扣hot100】 1. 两数之和
数据结构·c++·算法·leetcode·职场和发展
hoiii1878 分钟前
CSTR反应器模型的Simulink-PID仿真(MATLAB实现)
开发语言·matlab
炘爚40 分钟前
C++ 右值引用与程序优化
开发语言·c++
si莉亚1 小时前
ROS2安装EVO工具包
linux·开发语言·c++·开源
清心歌1 小时前
CopyOnWriteArrayList 实现原理
java·开发语言
良木生香1 小时前
【C++初阶】C++入门相关知识(2):输入输出 & 缺省参数 & 函数重载
开发语言·c++
忘梓.1 小时前
墨色规则与血色节点:C++红黑树设计与实现探秘
java·开发语言·c++
hhh3u3u3u1 小时前
Visual C++ 6.0中文版安装包下载教程及win11安装教程
java·c语言·开发语言·c++·python·c#·vc-1
星河耀银海2 小时前
C++ 模板进阶:特化、萃取与可变参数模板
java·开发语言·c++
泛凡(Linyongui)2 小时前
PY32F002B实践之二--宠物腹背理疗仪项目介绍及头文件解析
c语言·keil·py32·32位单片机·腹背理疗仪项目实践