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 《数据结构》(第二版) 陈越主编

  • 相关阅读:
    POJ 3710 Christmas Game#经典图SG博弈
    POJ 2599 A funny game#树形SG(DFS实现)
    POJ 2425 A Chess Game#树形SG
    LeetCode Array Easy 122. Best Time to Buy and Sell Stock II
    LeetCode Array Easy121. Best Time to Buy and Sell Stock
    LeetCode Array Easy 119. Pascal's Triangle II
    LeetCode Array Easy 118. Pascal's Triangle
    LeetCode Array Easy 88. Merge Sorted Array
    ASP.NET MVC 学习笔记之 MVC + EF中的EO DTO ViewModel
    ASP.NET MVC 学习笔记之面向切面编程与过滤器
  • 原文地址:https://www.cnblogs.com/Manual-Linux/p/11338576.html
Copyright © 2011-2022 走看看