zoukankan      html  css  js  c++  java
  • 二叉搜索树的相关算法

    二叉搜索树的算法主要包括:

    • 从二叉搜索树中查找元素,并返回其所在节点的地址
    • 查找二叉搜索树的最大元素
    • 查找二叉搜索树的最小元素
    • 二叉搜索树中插入元素
    • 二叉搜索树中删除元素

    相关代码实现如下:

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include"queue.h"
    #define NoInfo 0  //用0表示没有节点
    
    //作用:层序生成二叉树
    struct TNode* CreatBinTree()
    {
    	int Data;
    	struct QNode* Q = CreatQueue(10);  //创建空队列
    	struct TNode* T;
    	struct TNode* BT;
    
    	//建立第一个节点,即根节点
    	scanf("%d", &Data);
    	if (Data != NoInfo)
    	{
    		//动态分配一个结点单元,并存入数据,同时将该结点地址放入队列
    		BT = (struct TNode *)malloc(sizeof(struct TNode));
    		BT->Data = Data;
    		BT->Left = NULL;
    		BT->Right = NULL;
    		AddQ(Q, BT);
    	}
    	else
    	{
    		return NULL;
    	}
    
    	while (!IsEmpty(Q))
    	{
    		T = DeleteQ(Q);  //从队列中取出一节点地址
    		scanf("%d", &Data);
    		if (Data != NoInfo)
    		{
    			//动态分配一个结点单元,并存入数据,同时将该结点地址放入队列
    			T->Left = (struct TNode *)malloc(sizeof(struct TNode));
    			T->Left->Data = Data;
    			T->Left->Left = NULL;
    			T->Left->Right = NULL;
    
    			AddQ(Q, T->Left);
    		}
    		else
    		{
    			T->Left = NULL;
    		}
    		//读入右孩子的数据
    		scanf("%d", &Data);
    		if (Data != NoInfo)
    		{
    			//动态分配一个结点单元,并存入数据,同时将该结点地址放入队列
    			T->Right = (struct TNode *)malloc(sizeof(struct TNode));
    			T->Right->Data = Data;
    			T->Right->Left = NULL;
    			T->Right->Right = NULL;
    
    			AddQ(Q, T->Right);
    		}
    		else
    		{
    			T->Right = NULL;
    		}
    	} //end while (!IsEmpty(Q))
    	return BT;
    }
    //作用:在二叉搜索树中查找一个元素
    //参数:待查找的元素
    //返回值:返回其所在节点的位置
    //思路:递归实现
    struct TNode* Find(struct TNode* BST,int x)
    {
    	if (BST == NULL)
    	{
    		return NULL;
    	}
    	if (x > BST->Data)
    	{
    		return Find(BST->Right,x);  //在右子树中递归查找
    	}
    	else if(x < BST->Data)
    	{
    		return Find(BST->Left,x);
    	}
    	else
    	{
    		return BST;
    	}
    }
    //作用:在二叉搜索树中查找一个元素
    //参数:待查找的元素
    //返回值:返回其所在节点的位置
    //思路:非递归实现
    struct TNode* Find2(struct TNode* BST, int x)
    {
    	while (BST)
    	{
    		if (BST == NULL)
    		{
    			return NULL;
    		}
    		if (x > BST->Data)
    		{
    			BST = BST->Right;
    		}
    		else if (x < BST->Data)
    		{
    			BST = BST->Left;
    		}
    		else
    		{
    			break;
    		}
    	}
    	return BST;
    }
    //作用:查找二叉搜索树中最大元素的位置
    //思路:只要从根节点开始,当其不为空时,沿着右分支逐个判断各节点
    //      的指针,直到遇到空指针为止,从右分支找到的是最大元素
    struct TNode* FindMax(struct TNode* BST)
    {
    	if (BST != NULL)
    	{
    		while (BST->Right)
    		{
    			BST = BST->Right;
    		}
    	}
    	return BST;
    }
    //作用:查找二叉搜索树中最小元素的位置
    //思路:只要从根节点开始,当其不为空时,沿着右分支逐个判断各节点
    //      的指针,直到遇到空指针为止,从左分支找到的是最大元素
    struct TNode* FindMin(struct TNode* BST)
    {
    	if (BST != NULL)
    	{
    		while (BST->Left)
    		{
    			BST = BST->Left;
    		}
    	}
    	return BST;
    }
    //作用:二叉搜索树中插入元素
    struct TNode* Insert(struct TNode* BST,int x)
    {
    	if (BST == NULL)  //若原树为空,生成并返回一个结点的二叉搜索树
    	{
    		BST = (struct TNode*)malloc(sizeof(struct TNode));
    		BST->Data = x;
    		BST->Left = NULL;
    		BST->Right = NULL;
    	}
    	else  //开始找要插入元素的位置
    	{
    		if (x < BST->Data)
    		{
    			BST->Left = Insert(BST->Left,x);
    		}
    		else if (x > BST->Data)
    		{
    			BST->Right = Insert(BST->Right, x);
    		}
    	}
    	return BST;
    }
    //作用:二叉树的递归中序遍历
    void InorderTraversal(struct TNode* BT)
    {
    	if (BT)
    	{
    		InorderTraversal(BT->Left);
    		printf("%d. ", BT->Data);
    		InorderTraversal(BT->Right);
    	}
    }
    //作用:二叉搜索树中删除元素
    struct TNode* Delete(struct TNode* BST,int x)
    {
    	struct TNode* Tmp;
    	if (BST == NULL)
    	{
    		printf("要删除的元素未找到.
    ");
    	}
    	else
    	{
    		if (x < BST->Data)
    		{
    			BST->Left = Delete(BST->Left, x);  //从左子树递归删除
    		}
    		else if (x > BST->Data)
    		{
    			BST->Right = Delete(BST->Right, x);  //从右子树递归删除
    		}
    		else  //BST就是要删除的节点
    		{
                //如果被删除的节点有左右两个节点
    			if (BST->Left && BST->Right)
    			{
    				Tmp = FindMin(BST->Right);  //从右子树中找到最小的元素填充删除节点
    				BST->Data = Tmp->Data;
    				BST->Right = Delete(BST->Right,BST->Data);
    			}
    			else  //被删除节点有一个或无子节点
    			{
    				Tmp = BST;
    				if (!BST->Left)  //只有右孩子或无子节点
    				{
    					BST = BST->Right;
    				}
    				else
    				{
    					BST = BST->Left;
    				}
    				free(Tmp);
    			}
    		}
    	}
    	return BST;
    }
    
    int main()
    {
    	struct TNode* BT = CreatBinTree();
    	struct TNode* BST = Find(BT, 50);
    	if (BST != NULL)
    	{
    		printf("查找到元素: %d.
    ", BST->Data);
    	}
    	else
    	{
    		printf("二叉搜索树中没有要查找的元素.
    ");
    	}
    	struct TNode* BST2 = Find2(BT, 41);
    	if (BST2 != NULL)
    	{
    		printf("查找到元素: %d.
    ", BST2->Data);
    	}
    	else
    	{
    		printf("二叉搜索树中没有要查找的元素.
    ");
    	}
    	struct TNode* BSTMAX = FindMax(BT);
    	if (BSTMAX != NULL)
    	{
    		printf("二叉搜索树中最大的元素是: %d.
    ", BSTMAX->Data);
    	}
    	struct TNode* BSTMIN = FindMin(BT);
    	if (BSTMIN != NULL)
    	{
    		printf("二叉搜索树中最小的元素是: %d.
    ", BSTMIN->Data);
    	}
    
    	Insert(BT,35);
    	InorderTraversal(BT);
    	Delete(BT,20);
    	InorderTraversal(BT);
    	system("pause");
    	return 0;
    }
    

    实现队列的头文件和.c文件

    queue.h

    #pragma once
    //二叉树的创建需要队列
    //该文件实现队列的一系列操作
    #pragma once
    #include<stdio.h>
    #include<stdbool.h>
    #include<stdlib.h>
    
    struct TNode
    {
    	int Data;  //节点的数据
    	struct TNode* Left;  //指向左子树
    	struct TNode* Right;  //指向右子树
    };
    
    typedef struct TNode* ElementType;
    
    struct QNode
    {
    	ElementType* Data;  //存储元素的数组
    	int Front;  //队列的头指针
    	int Rear;  //队列的尾指针
    	int MaxSize;  //队列的最大容量
    };
    
    struct QNode* CreatQueue(int MaxSize);
    bool IsFull(struct QNode* Q);
    bool AddQ(struct QNode* Q, ElementType x);
    bool IsEmpty(struct QNode* Q);
    ElementType DeleteQ(struct QNode* Q);
    
    

    queue.c

    #include<stdio.h>
    #include"queue.h"
    //作用:创建一个队列
    //参数:队列的大小
    struct QNode* CreatQueue(int MaxSize)
    {
    	struct QNode* Q = (struct QNode *)malloc(sizeof(struct QNode));
    	Q->Data = (ElementType *)malloc(MaxSize * sizeof(int));
    	Q->Front = Q->Rear = 0;
    	Q->MaxSize = MaxSize;
    	return Q;
    }
    //作用:判断当前队列是否满
    //参数:待判断的队列
    bool IsFull(struct QNode* Q)
    {
    	return ((Q->Rear + 1) % Q->MaxSize == Q->Front);
    }
    //作用:向队列中插入元素
    //参数:struct QNode* Q 待插入的队列
    //      int x 待插入的元素
    bool AddQ(struct QNode* Q, ElementType x)
    {
    	if (IsFull(Q))  //判断队列是否为空
    	{
    		printf("队列满,不能再插入元素
    ");
    		return false;
    	}
    	else
    	{
    		Q->Rear = (Q->Rear + 1) % Q->MaxSize;
    		Q->Data[Q->Rear] = x;
    		return true;
    	}
    }
    //作用:判断队列是否为空
    //参数:
    //返回值: true   空
    //         false  非空
    bool IsEmpty(struct QNode* Q)
    {
    	return (Q->Front == Q->Rear);
    }
    //作用:
    //参数:
    ElementType DeleteQ(struct QNode* Q)
    {
    	if (IsEmpty(Q))
    	{
    		printf("队列为空
    ");
    		return NULL;
    	}
    	else
    	{
    		Q->Front = (Q->Front + 1) % Q->MaxSize;
    		return Q->Data[Q->Front];
    	}
    }
    

    参考资料:

    1 《数据结构》(第二版) 陈越主编

  • 相关阅读:
    [CF1039D]You Are Given a Tree
    [洛谷P2107]小Z的AK计划
    [CF409F]000001
    [洛谷P1801]黑匣子_NOI导刊2010提高(06)
    [洛谷P3377]【模板】左偏树(可并堆)
    [洛谷P2482][SDOI2010]猪国杀
    [CF45G]Prime Problem
    [CF735D]Taxes
    [洛谷P3413]SAC#1
    [洛谷P4124][CQOI2016]手机号码
  • 原文地址:https://www.cnblogs.com/Manual-Linux/p/11338576.html
Copyright © 2011-2022 走看看