zoukankan      html  css  js  c++  java
  • “二叉查找树”学习

    查找二叉树的定义:

    image

    存储结构和二叉树相同:

    image

    需要实现的方法:

    image

    代码:

    tree.h

    #ifndef _TREE_H
    #define _TREE_H
    
    typedef int ElemType;
    
    typedef struct treenode
    {
    	ElemType data;
    	struct treenode * left;
    	struct treenode * right;
    }TREE;
    
    
    
    TREE *MakeEmptyTree();
    
    TREE *InsertTreeNode(ElemType e,TREE *t);
    
    TREE *FindTreeNode(ElemType e,TREE *t);
    
    TREE *FindMax(TREE *t);
    
    TREE *FindMin(TREE *t);
    
    TREE *DeleteTreeNode(ElemType e,TREE *t);
    
    void DeleteTree(TREE **t);
    
    #endif

    tree.c

    #include<stdio.h>
    #include<stdlib.h>
    #include"tree.h"
    
    
    TREE *MakeEmptyTree()
    {
    	return NULL;
    }
    
    TREE *InsertTreeNode(ElemType e,TREE *t)
    {
    	if(t == NULL)
    	{
    		t = (TREE *)malloc(sizeof(TREE));
    		if(t == NULL) return NULL;
    		t->data = e;
    		t->left = t->right = NULL;
    	}else if(e < t->data)
    		t->left = InsertTreeNode(e,t->left);
    	else
    		t->right = InsertTreeNode(e,t->right);
    	return t;
    }
    
    TREE *FindTreeNode(ElemType e,TREE *t)
    {
    	if(t == NULL) return NULL;
    	if(t->data == e)
    		return t;
    	else if(t->data < e)
    		return FindTreeNode(e,t->right);
    	else 
    		return FindTreeNode(e,t->left);
    }
    
    TREE *FindMax(TREE *t)
    {
    	if(t == NULL)
    		return NULL;
    	if(t->right == NULL)
    		return t;
    	return FindMax(t->right);
    }
    
    TREE *FindMin(TREE *t)
    {
    	if(t == NULL)return NULL;
    	if(t->left == NULL)
    		return t;
    	return FindMin(t->left);
    }
    
    TREE *DeleteTreeNode(ElemType e,TREE *t)
    {
    	TREE *p = NULL;
    	if(t == NULL)return NULL;
    	if(t->data > e)//数据比根小
    		t->left = DeleteTreeNode(e,t->left);//去左子树删
    	else if(t->data < e)
    		t->right = DeleteTreeNode(e,t->right);//去右子树删
    	//这个节点就是要删的
    	else if(t->left && t->right)//有两个子节点的节点
    	{
    		//找出右子树里最小的
    		p = FindMin(t->right);
    		t->data = p->data;
    		t->right = DeleteTreeNode(t->data,t->right);
    	}else//要删除的节点有一个子节点或就是叶子节点
    	{
    		p = t;
    		if(t->left == NULL)//右数有
    			t = t->right;
    		else if(t->right == NULL)
    			t = t->left;
    		free(p);
    		return t;
    	}
    	return t;
    
    }
    
    void DeleteTree(TREE **t)
    {
    	if(*t == NULL)
    		return;
    	DeleteTree(&((*t)->left));
    	DeleteTree(&((*t)->right));
    	free(*t);
    	*t = NULL;
    }

    重点解释一下删除一个节点的算法:

    包括两种情况,首先这种是要删除单子树节点的情况:

    else//要删除的节点有一个子节点或就是叶子节点
    {
    	p = t;
    	if(t->left == NULL)//右数有
    		t = t->right;
    	else if(t->right == NULL)
    		t = t->left;
    	free(p);
    	return t;
    }

    image

    这里是只有左子树,那么只要把他的左节点挂到根上面去。程序实现就是直接返回这个左节点。

    image

    image

    如果要删除的是叶子节点,比如删除上图的3,那么执行第一条语句时:

    if(t->left == NULL) t = t->right;

    就已经把t赋值为右数,第二条赋值左树,都是NULL所以最终t就是NULL,返回的也就是NULL。

    释放p,就是原来的t,就成功删除了叶子节点3.

    image

    image

    第二种情况就是要删除的是有双子树的一个节点:

    image

    else if(t->left && t->right)//有两个子节点的节点
    {
    	//找出右子树里最小的
    	p = FindMin(t->right);
    	t->data = p->data;
    	t->right = DeleteTreeNode(t->data,t->right);
    }

    我们可以找出右子树的最小的节点,当然也可以是左子树最大的节点,先把它的数据提上来,将它递归删除掉。

    image

    image

    testBSTree.c

    #include<stdio.h>
    #include"tree.h"
    
    void main()
    {
    	int n;
    	TREE *tree = MakeEmptyTree(),*p;
    	while(1)
    	{
    		printf("Please enter a num:");
    		fflush(stdin);
    		if(scanf("%d",&n) != 1)
    			break;
    		if(n == 0)
    			break;
    		tree = InsertTreeNode(n,tree);
    	}
    	printf("Max of tree is %d,min of tree is %d\n",
    		FindMax(tree)->data,FindMin(tree)->data);
    
    
    	fflush(stdin);
    	printf("Please enter search num:");
    	scanf("%d",&n);
    	if(FindTreeNode(n,tree))
    		printf("find %d\n",n);
    	else
    		printf("not find\n");
    
    	p = DeleteTreeNode(n,tree);
    	if(p)
    		printf("delete %d success\n",n);
    	else
    		printf("delete fail\n");
    
    	DeleteTree(&tree);
    	if(tree == NULL)
    		printf("delete success\n");
    	else
    		printf("fail\n");
    }

    运行时:

    image

    可以看到最大值输出76,最小值4,找到7,删除了7这个节点,进而删除了整棵树。

  • 相关阅读:
    【React Native】某个页面禁用物理返回键
    【React Native】DeviceEventEmitter监听通知及带参数传值
    转载【React Native代码】手写验证码倒计时组件
    【React Native】 中设置 APP 名称、应用图标、为安卓添加启动图
    【React Native错误集】* What went wrong: Execution failed for task ':app:installDebug'.
    【React Native错误集】Import fails with "Failed to execute 'ImportScripts' on 'WorkerGlobalScope'"
    【React Native错误集】Android error “Could not get BatchedBridge, make sure your bundle is packaged properly” on start of app
    「React Native笔记」在React的 setState 中操作数组和对象的多种方法(合集)
    【React Native】Error: Attribute application@allowBackup value=(false) from AndroidManifest.xml
    坚果云如何使用二次验证码/谷歌身份验证器/两步验证/虚拟MFA?
  • 原文地址:https://www.cnblogs.com/shenerguang/p/2336968.html
Copyright © 2011-2022 走看看