【数据结构与算法】二叉树的创建,插入,遍历,删除,删除节点实现
二叉树是每个结点最多有两个子树的树结构。使用广泛,使用C来实现对二叉树的操作。
示例:代码实现构造如下二叉树
#include <iostream>
using namespace std;
typedef struct BinaryTree
{
int data;
struct BinaryTree* lchild;
struct BinaryTree* rchild;
}BiTNode;
/************************************
@ Brief: 二叉树中插入节点
@ Author: woniu201
@ Created: 2019/07/10
@ Return:
************************************/
void insertNode(BiTNode** node, int val)
{
BiTNode* tmpNode = NULL;
if (!(* node))
{
tmpNode = (BiTNode*)malloc(sizeof(BiTNode));
memset(tmpNode, 0, sizeof(BiTNode));
tmpNode->data = val;
*node = tmpNode;
return;
}
if (val < (*node)->data)
{
insertNode(&(*node)->lchild, val);
}
else if (val > (*node)->data)
{
insertNode(&(*node)->rchild, val);
}
return;
}
/************************************
@ Brief: 删除节点
@ Author: woniu201
@ Created: 2019/07/10
@ Return: 参考:https://blog.csdn.net/Future_LL/article/details/79968437
************************************/
void delNode(BiTNode* node, int val)
{
BiTNode *L, *LL; //在删除左右子树都有的结点时使用;
BiTNode *p = node;
BiTNode *parent = node;
int child = 0; //0表示左子树,1表示右子树;
if (!node) //如果排序树为空,则退出;
{
return;
}
while (p) //二叉排序树有效;
{
if (p->data == val)
{
if (!p->lchild && !p->rchild) //叶结点(左右子树都为空);
{
if (p == node) //被删除的结点只有根结点;
free(p);
else if (child == 0)
{
parent->lchild = NULL; //设置父结点左子树为空;
free(p); //释放结点空间;
}
else //父结点为右子树;
{
parent->rchild = NULL; //设置父结点右子树为空;
free(p); //释放结点空间;
}
}
else if (!p->lchild) //左子树为空,右子树不为空;
{
if (child == 0) //是父结点的左子树;
parent->lchild = p->rchild;
else //是父结点的右子树;
parent->rchild = p->rchild;
free(p); //释放被删除的结点;
}
else if (!p->rchild) //右子树为空,左子树不为空;
{
if (child == 0) //是父结点的左子树;
parent->lchild = p->lchild;
else //是父结点的右子树;
parent->rchild = p->lchild;
free(p); //释放被删除的结点;
}
else
{
LL = p; //保存左子树的结点;
L = p->rchild; //从当前结点的右子树进行查找;
if (L->lchild) //左子树不为空;
{
LL = L;
L = L->lchild; //查找左子树;
p->data = L->data; //将左子树的数据保存到被删除结点;
LL->lchild = L->lchild; //设置父结点的左子树指针为空;
for (; L->lchild; L = L->lchild);
L->lchild = p->lchild;
p->lchild = NULL;
}
else
{
p->data = L->data;
LL->rchild = L->rchild;
}
}
p = NULL;
}
else if (val < p->data) //需删除记录的关键字小于结点的数据;
{
//要删除的结点p是parent的左子树;
child = 0; //标记在当前结点左子树;
parent = p;//保存当前结点作为父结点;
p = p->lchild; //查找左子树;
}
else //需删除记录的关键字大于结点的数据;
{
//要删除的结点p是parent的右子树;
child = 1; //标记在当前结点右子树查找;
parent = p; //保存当前结点作为父结点;
p = p->rchild; //查找右子树;
}
}
return;
}
/************************************
@ Brief: 删除树
@ Author: woniu201
@ Created: 2019/07/10
@ Return:
************************************/
void delTree(BiTNode* node)
{
if (node)
{
delTree(node->lchild);
delTree(node->rchild);
free(node);
node = NULL;
}
}
/************************************
@ Brief: 前序遍历
@ Author: woniu201
@ Created: 2019/07/10
@ Return:
************************************/
void proorder(BiTNode* node)
{
if (node)
{
printf("%d ", node->data);
proorder(node->lchild);
proorder(node->rchild);
}
}
/************************************
@ Brief: 中序遍历
@ Author: woniu201
@ Created: 2019/07/10
@ Return:
************************************/
void inorder(BiTNode* node)
{
if (node)
{
inorder(node->lchild);
printf("%d ", node->data);
inorder(node->rchild);
}
}
/************************************
@ Brief: 后序遍历
@ Author: woniu201
@ Created: 2019/07/10
@ Return:
************************************/
void postorder(BiTNode* node)
{
if (node)
{
postorder(node->lchild);
postorder(node->rchild);
printf("%d ", node->data);
}
}
int main()
{
BiTNode* node = NULL;
insertNode(&node, 10);
insertNode(&node, 15);
insertNode(&node, 8);
insertNode(&node, 9);
insertNode(&node, 17);
insertNode(&node, 6);
insertNode(&node, 11);
//前序遍历
printf("先序遍历:\n");
proorder(node);
//中序遍历
printf("\n中序遍历:\n");
inorder(node);
//后序遍历
printf("\n后序遍历:\n");
postorder(node);
//删除节点
delNode(node, 15);
//删除树
delTree(node);
return 1;
}
作者:蜗牛201 出处:https://www.cnblogs.com/woniu201/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。 如果文中有什么错误,欢迎指出。以免更多的人被误导。 |