【数据结构与算法】二叉树的创建,插入,遍历,删除,删除节点实现

二叉树是每个结点最多有两个子树的树结构。使用广泛,使用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;
}

posted @ 2019-07-10 17:03  蜗牛201  阅读(808)  评论(0编辑  收藏  举报