数据结构——二叉搜索树

二叉搜索树(二叉排序树、二叉查找树)

1.定义

二叉搜索树(Binary Search Tree):用于排序和查找都很有用的特殊二叉树。在以下操作中,规定各结点彼此键值不同

2.性质

(1)非空左子树的所有键值小于其根节点的键值;
(2)非空右子树的所有键值大于其根节点的键值;
(3)左、右子树都是二叉搜索树;

3.抽象数据类型

类型名称:二叉搜索树(Binary Search Tree)
数据对象集:一个有穷的结点集合。这个集合可以为空,若不为空,则由根节点和其左、右二叉子树组成。
操作集:对于所有BT属于BinTree,有
(1)bool IsEmpty(BinTree BT):若BT为空返回true;否则返回false
(2)void Traversal(BinTree BT):二叉树的遍历
(3)BinTree CreatBinTree():创建一个二叉树
(4)Position Find(BinTree BST,ElementType X):从二叉搜索树BST中查找元素X,返回其所在结点的地址;
(5)Position FindMin(BinTree BST):从二叉搜索树中查找并返回最小元素所在结点的地址
(6)Position FindMax(BinTree BST):从二叉搜索树中查找并返回最大元素所在结点的地址

4.C语言实现(重点为插入与删除)

//二叉搜索树 
#include<stdio.h>
#include<stdlib.h>
#define NoInfo 0
#define ERROR NULL
typedef int ElementType;

typedef struct TNode * Position_TNode;
typedef struct TNode * BinTree; /* 二叉树类型 */

typedef struct Node * PtrToNode;
typedef struct Node * Position_Node;

typedef struct QNode * PtrToQNode;
typedef struct QNode * Queue;


struct TNode{ /* 树结点定义 */
    ElementType Data; /* 结点数据 */
    BinTree Left;     /* 指向左子树 */
    BinTree Right;    /* 指向右子树 */
};
struct Node { /* 队列中的结点 */
    BinTree Data_BinTree;//结点数据为BinTree类型的指针 
    PtrToNode Next;
};
struct QNode {
    Position_Node Front;
	Position_Node Rear;  /* 队列的头、尾指针 */
    
};
//bt打印 
BinTree DeleteQ( Queue Q );
bool AddQ(Queue Q,BinTree x);
Queue CreateQueue();
bool IsEmpty( Queue Q );
void LevelorderTraversal(BinTree BT);//层序打印 
//二叉搜索树创建(插入)即及删除 
Position_TNode Find(BinTree BST,ElementType X);//二叉搜索树的查找 
Position_TNode FindMax(BinTree BST);//查找二叉搜索树中最大值 
Position_TNode FindMin(BinTree BST);//最小值 
BinTree Insert(BinTree BST,ElementType X);//二叉搜索树的插入 
BinTree Delete(BinTree BST,ElementType X);//二叉搜索树的删除 

int main(){
	BinTree bst=NULL;
//         30 
//     15     41
//         33      50          
//            35          
//         34 

	bst=Insert(bst,30);
	bst=Insert(bst,15);
	bst=Insert(bst,41);
	bst=Insert(bst,33);
	bst=Insert(bst,50);
	bst=Insert(bst,35);
	bst=Insert(bst,34);
	LevelorderTraversal(bst);
	return 0;
}
BinTree DeleteQ( Queue Q )
{
    Position_Node FrontCell; 
    BinTree FrontElem;

    if  ( IsEmpty(Q) ) {
        printf("队列空");
        return ERROR;
    }
    else {
        FrontCell = Q->Front;
        if ( Q->Front == Q->Rear ) /* 若队列只有一个元素 */
            Q->Front = Q->Rear = NULL; /* 删除后队列置为空 */
        else                     
            Q->Front = Q->Front->Next;
        FrontElem = FrontCell->Data_BinTree;
 
        free( FrontCell );  /* 释放被删除结点空间  */
        return  FrontElem;
    }
}

Queue CreateQueue()
{
	Queue Q=(Queue)malloc(sizeof(struct QNode));
	Q->Front=Q->Rear=NULL;
	return Q;
}
bool IsEmpty( Queue Q )
{
    return ( Q->Front == NULL);
}
bool AddQ(Queue Q,BinTree x)
{
	Position_Node RearCell=(Position_Node)malloc(sizeof(struct Node));
	
	if(IsEmpty(Q)){
		Q->Front=Q->Rear=RearCell;
		Q->Rear->Data_BinTree=x;
		Q->Rear->Next=NULL;
	}
	else{
		Q->Rear->Next=RearCell;
		Q->Rear=RearCell;
		Q->Rear->Data_BinTree=x;
		Q->Rear->Next=NULL;
	}	
}
void LevelorderTraversal(BinTree BT){
	Queue Q;
	Q=CreateQueue();
	BinTree T;

	AddQ(Q,BT);
	while(!IsEmpty(Q)){
		T=DeleteQ(Q);
		printf(" %d ",T->Data);
		if(T->Left)  AddQ(Q,T->Left);
		if(T->Right) AddQ(Q,T->Right);
		
	}	
}
Position_TNode Find(BinTree BST,ElementType X){
	while(BST){
		if(X>BST->Data){
			BST=BST->Right;
		}
		else if(X<BST->Data){
			BST=BST->Left;
		}
		else break;
	}
	return BST;
}
//递归实现查找 
//Position_TNode Find(BinTree BST,ElementType X)
//{
//	if(!BST) return NULL;
//	if(X>BST->Data) return Find(BST->Right,X);
//	else if(X<BST->Data) return Find(BST->Left,X);
//	else return BST;//X==BST->Data
//}
Position_TNode FindMin(BinTree BST){
	if(!BST) return NULL;
	else if(!BST->Left) return BST;
	else return FindMin(BST->Left);
}
Position_TNode FindMax(BinTree BST){
	if(!BST) return NULL;
	else if(!BST->Right) return BST;
	else return FindMax(BST->Right);
}
BinTree Insert(BinTree BST,ElementType X){
	BinTree bst;//bst为待插入的结点 
	BinTree tmp,bst_fatherNode;//tmp为遍历树的指针,bsst_fatherNode为bst的父节点 
	
	bst_fatherNode=(BinTree)malloc(sizeof(struct TNode));
	bst_fatherNode->Left=bst_fatherNode->Right=NULL;
	tmp=(BinTree)malloc(sizeof(struct TNode));
	tmp->Left=tmp->Right=NULL;
	bst=(BinTree)malloc(sizeof(struct TNode));
	bst->Left=bst->Right=NULL;
	//初始化各指针 
	if(!BST){
		BST=(BinTree)malloc(sizeof(struct TNode));
		BST->Data=X;
		BST->Left=BST->Right=NULL;
	}//若树为空直接插入头结点 
	else{
		tmp=BST;//由于需返回树,故用 tmp指针 查找 新节点 应插入的位置 
		while(tmp){//当tmp为NULL说明 tmp位置 为 将要被插入的结点 的位置 
			if(X<tmp->Data){
				bst_fatherNode=tmp;//记录被插入结点的父节点,便于构建二叉树 
				tmp=tmp->Left;
			}
			else if(X>tmp->Data){
				bst_fatherNode=tmp;
				tmp=tmp->Right;
			}
		}
		if(X<bst_fatherNode->Data){
			bst->Data=X;
			bst_fatherNode->Left=bst;//将父节点的左指针 指向 被插入的结点 
			bst->Left=bst->Right=NULL;
		} 
		if(X>bst_fatherNode->Data){
			bst->Data=X;
			bst_fatherNode->Right=bst;
			bst->Left=bst->Right=NULL;
		}
		
	}
		 
	return BST;
}
//递归实现插入 
//BinTree Insert(BinTree BST,ElementType X){
//	if(!BST){
//		BST=(BinTree)malloc(sizeof(struct TNode));
//		BST->Data=X;
//		BST->Left=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);
//		}
//		//规定了各结点键值不同,故若BST->Data==X则什么都不做 
//	}
//  return BST; 
//}
BinTree Delete(BinTree BST,ElementType X){
	Position_TNode Tmp;
	if( !BST ) 
        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; 
//当无子结点时,让 被删除结点的父节点 指向 被删除结点 的指针 指向NULL(BST->Left==NULL)
                else                   /* 只有左孩子 */
                    BST = BST->Left;
 
                free( Tmp );
            }
        }
    }
    return BST;//删除中的遍历改变的是BST->Left和BST->Right指针,故BST仍指向根节点 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值