通过二叉树完成文本输出
作者:互联网
同过二叉树完成文本输出与链表大同小异。
目标头文件
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define IS_NOT_LETTER(C) (!((C>='a' && C<='z') || (C>='A' && C<='Z')))
二叉树定义
struct treenode
{
struct treenode* parent;
struct treenode* lchild;
struct treenode* rchild;
void* data;
};
struct tree
{
struct treenode* root;
int (*comp)(void* node1, void* node2);
};
初始二叉树
struct tree* firsttree(int(*comp)(void* node1,void* node2))
{
struct tree* mytree = (struct tree*)malloc(sizeof(struct tree));
struct treenode*root = (struct treenode*)malloc(sizeof(struct treenode));
mytree->root = root;
root->parent = NULL;
root->lchild = NULL;
root->rchild = NULL;
root->data = NULL;
mytree->comp = comp;
return mytree;
}
插入
//插入
struct treenode* addtreenode(struct tree* mytree, struct treenode* node,char* pstrat,int wordsize)
{
if (pstrat == NULL || mytree == NULL)
{
return NULL;
}
if (mytree->root->data == NULL)
{
(char*)node->data ;
node->data= (char*)malloc(sizeof(char)*(wordsize+1));
memset(node->data, 0, wordsize + 1);
memcpy(node->data, pstrat, wordsize);
}
else
{
if (node == NULL)
{
node = (struct treenode*)malloc(sizeof(struct treenode));
(char*)node->data ;
node->data= (char*)malloc(sizeof(char) * (wordsize + 1));
memset(node->data, 0, wordsize + 1);
memcpy(node->data, pstrat, wordsize);
node->lchild = NULL;
node->rchild = NULL;
}
else
{
if (comp(node->data, pstrat) > 0)
{
node->lchild = addtreenode(mytree, node->lchild,pstrat,wordsize);
node->lchild->parent = node;
}
else
{
node->rchild = addtreenode(mytree, node->rchild,pstrat,wordsize);
node->rchild->parent = node;
}
}
}
return node;
}
查找
//根据值查找某一特定节点
struct treenode* find(struct tree* mytree, struct treenode* node, void* data)
{
if (mytree == NULL || data == NULL)
{
return NULL;
}
if (node != NULL)
{
if (comp(node->data, data) == 0)
return node;
if (comp(node->data, data) > 0)
return find(mytree, node->lchild, data);
if (comp(node->data, data) < 0)
return find(mytree, node->rchild, data);
}
}
删除
struct treenode* dele(struct tree* mytree, struct treenode* temp, void* data)
{
struct treenode* node=find(mytree, temp, data);
struct treenode* parent = node->parent;
if (node == NULL) //待删节点不存在
printf("没有待删节点\n");
else //待删节点存在
{
if (node->lchild == NULL && node->rchild == NULL) //如果待删节点是叶子节点
{
// assert(parent != NULL);
if (parent == NULL) //如果是根节点
{
mytree->root = NULL;
mytree->root= NULL;
}
else //其他节点
{
if (node == parent->lchild)
parent->lchild = NULL;
else
parent->rchild = NULL;
}
}
else if (node->rchild == NULL) //如果待删节点只有左子树节点
{
if (parent == NULL)//如果是根节点
{
struct treenode* lchild = node->lchild;
free(mytree->root->data);
mytree->root->data = lchild->data;
mytree->root->lchild = lchild->lchild;
mytree->root->rchild = lchild->rchild;
}
else //其他节点
{
if (node == parent->lchild)
{
node->lchild->parent = parent;
parent->lchild = node->lchild;
}
else
{
node->lchild ->parent=parent;
parent->rchild = node->lchild;
}
}
}
else if (node->lchild == NULL) //如果待删节点只有右子树节点
{
if (parent == NULL) //如果是根节点
{
struct treenode* rchild = node->rchild;
free(mytree->root->data);
mytree->root->data= rchild->data;
mytree->root->lchild = rchild->lchild;
mytree->root->rchild = rchild->rchild;
}
else //其他节点
{
if (node== parent->lchild)
{
node->rchild->parent = parent;
parent->lchild = node->rchild;
}
else
{
node->rchild->parent = parent;
parent->rchild = node->rchild;
}
}
}
else if(node->lchild!=NULL&&node->rchild!=NULL) //如果带删节点左右子树节点都存在
{
struct treenode* new_node = node->rchild;
while (new_node->lchild != NULL)
{
new_node = new_node->lchild;
}
if (temp == node)//删除节点为根节点
{
if (new_node != temp->rchild)
{
if (new_node->rchild != NULL)
{
new_node->rchild->parent = new_node->parent;
new_node->parent->lchild = new_node->rchild;
}
else
{
new_node->parent->lchild = NULL;
}
free(mytree->root->data);
mytree->root->lchild->parent = new_node;
mytree->root->rchild->parent = new_node;
new_node->lchild = mytree->root->lchild;
new_node->rchild = mytree->root->rchild;
new_node->parent = mytree->root->parent;
mytree->root->data = new_node->data;
}
if (new_node == node->rchild)
{
node->lchild->parent = new_node;
new_node->lchild = node->lchild;
new_node->parent = node->parent;
}
}
else
{
if (new_node != node->rchild)
{
if (new_node->rchild != NULL)
{
new_node->rchild->parent=new_node->parent;
new_node->parent->lchild = new_node->rchild;
}
else
{
new_node->parent->lchild = NULL;
}
node->lchild->parent = new_node;
node->rchild->parent = new_node;
new_node->lchild = node->lchild;
new_node->rchild = node->rchild;
new_node->parent = node->parent;
}
if (new_node == node->rchild)
{
node->lchild->parent = new_node;
new_node->lchild = node->lchild;
new_node->parent = node->parent;
}
if (node == parent->lchild)
{
parent->lchild = new_node;
}
if ( node == parent->rchild)
{
parent->rchild = new_node;
}
}
}
}
}
遍历
//遍历
void show_all(struct tree* mytree, struct treenode* node, void(*myprintf)(void* data))
{
if (node != NULL && mytree != NULL)
{
if (node->lchild != NULL)
{
show_all(mytree, node->lchild, myprintf);
}
myprintf(node->data);
if (node->rchild != NULL)
{
show_all(mytree, node->rchild, myprintf);
}
}
}
自定义
//比较函数
int comp(void*data,void*pstrat)
{
int i = 0;
i=strcmp((char*)data, (char*)pstrat);
return i;
}
//打印函数
void myprintf(void* node)
{
if (node == NULL)
{
return;
}
printf(" % s\n", (char*)node);
return;
}
销毁二叉树
//销毁
struct treenode* freetree( struct treenode* node)
{
if (node->lchild != NULL)
{
node->lchild=freetree(node->lchild);
}
if (node->rchild != NULL)
{
node->rchild=freetree( node->rchild);
}
free(node->data);
//node->data = NULL;
free(node);
//node = NULL;
return node;
}
测试
//主函数
int main()
{
FILE*file=fopen("C:\\Users\\mint\\Desktop\\list\\list\\Project1\\test.txt", "r");
struct tree* mytree = firsttree(comp);
struct treenode* temp = NULL;
temp = mytree->root;
char line[100];
while (fgets(line, 100, file)!=NULL)
{
char* pstrat = line;
char* pend = line;
while (*pend != '\0'&&*pstrat!='\n')
{
if (IS_NOT_LETTER(*pend)&&(!IS_NOT_LETTER(*pstrat)))//防止换行后行首出现非字母符号
{
unsigned int wordsize = pend - pstrat;
addtreenode(mytree, temp, pstrat, wordsize);
pstrat = pend + 1;
}
if (*pend == '\n' || *pstrat == '\n')//防止末尾换行符号前存在多个非字母的符号
{
break;
}
while (IS_NOT_LETTER(*pstrat))
{
pend = pstrat;
pstrat++;
if (*pend == '\n' || *pstrat == '\n')//防止末尾换行符号前存在多个非字母的符号
{
break;
}
}
if (*pend == '\n'||*pstrat=='\n')//防止末尾换行符号前存在多个非字母的符号
{
break;
}
if (*(pend + 1) == '\0')
{
if (!IS_NOT_LETTER(*pend))
{
unsigned int wordsize = pend - pstrat + 1;
addtreenode(mytree, temp, pstrat, wordsize);
break;
}
}
pend++;
}
}
show_all(mytree, temp,myprintf);
char c[] = { "test" };
int wordsize = 4;
addtreenode(mytree, temp, c, wordsize);
show_all(mytree, temp, myprintf);
char b[] = { "n" };
dele(mytree, temp, b);
show_all(mytree, temp, myprintf);
freetree(temp);
free(mytree);
}
标签:node,输出,NULL,mytree,parent,二叉树,rchild,文本,lchild 来源: https://blog.csdn.net/qq_62567244/article/details/122403527