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


    二叉树是每个结点最多有两个子树的树结构。使用广泛,使用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("先序遍历:
    ");
    	proorder(node);
    
    	//中序遍历
    	printf("
    中序遍历:
    ");
    	inorder(node);
    
    
    	//后序遍历
    	printf("
    后序遍历:
    ");
    	postorder(node);
    
    	//删除节点
    	delNode(node, 15);
    
    	//删除树
    	delTree(node);
    
    	return 1;
    }

  • 相关阅读:
    PHP学习(二)
    PHP学习(一)
    JQuery学习小结
    Java学习(七)标准标签库JSTL
    Java学习(六)servlet 的引入
    Java学习(五)例题
    java学习(四)代码的设计
    Java学习(三)JSP学习1
    采用prometheus 监控mysql
    commonjs, nodejs, npm, browserify, watchify
  • 原文地址:https://www.cnblogs.com/woniu201/p/11694509.html
Copyright © 2020-2023  润新知