04-树7 二叉搜索树的操作集(30 分)非递归方法

本文探讨了如何在二叉搜索树中进行常规操作,重点介绍非递归方法。在删除节点时,若节点左右子树均非空,则需将其右子树最大值接至左子树。访问节点时需检查节点是否存在,避免访问空节点导致错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:搜索二叉树的常规操作。

思路:一般有两种,一种是递归调用,另一种是非递归的方法。我采用的是非递归的方法。

注意点:

1删除操作,一个节点左右都不为空,是将结点的右子树接到左子树的最大值的右孩子。

2访问节点时,一定要注意该节点是否为空,如果为空千万不要去访问节点的数据,不然会出错。

#include <stdio.h>
#include <stdlib.h>
#include<malloc.h>

typedef int ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};

void PreorderTraversal( BinTree BT ) /* 先序遍历,由裁判实现,细节不表 */
{
	if(BT){
		printf("%d ",BT->Data);
		PreorderTraversal(BT->Left);
		PreorderTraversal(BT->Right);
	} 
} 
void InorderTraversal( BinTree BT )  /* 中序遍历,由裁判实现,细节不表 */
{
	if(BT){
		InorderTraversal(BT->Left);
		printf("%d ",BT->Data);
		InorderTraversal(BT->Right);
	}
} 

BinTree Insert( BinTree BST, ElementType X );
BinTree Delete( BinTree BST, ElementType X );
Position Find( BinTree BST, ElementType X );
Position FindMin( BinTree BST );
Position FindMax( BinTree BST );

int main()
{
    BinTree BST, MinP, MaxP, Tmp;
    ElementType X;
    int N, i;

    BST = NULL;
    scanf("%d", &N);
    for ( i=0; i<N; i++ ) {
        scanf("%d", &X);
        BST = Insert(BST, X);
    }
    printf("Preorder:"); PreorderTraversal(BST); printf("\n");
    MinP = FindMin(BST);
    MaxP = FindMax(BST);
    scanf("%d", &N);
    for( i=0; i<N; i++ ) {
        scanf("%d", &X);
        Tmp = Find(BST, X);
        if (Tmp == NULL) printf("%d is not found\n", X);
        else {
            printf("%d is found\n", Tmp->Data);
            if (Tmp==MinP) printf("%d is the smallest key\n", Tmp->Data);
            if (Tmp==MaxP) printf("%d is the largest key\n", Tmp->Data);
        }
    }
    scanf("%d", &N);
    for( i=0; i<N; i++ ) {
        scanf("%d", &X);
        BST = Delete(BST, X);
    }
    printf("Inorder:"); InorderTraversal(BST); printf("\n");

    return 0;
}
BinTree Insert( BinTree BST, ElementType X )  //插入 
{
	BinTree p,pp,q=(BinTree)malloc(sizeof(BinTree)); //q插入的节点 ,pp插入节点q的父亲结点 
	q->Data=X;q->Left=NULL;q->Right=NULL;
	if(!BST)BST=q;
	else{
		p=BST;
		while(p){
			if(X<p->Data){pp=p;p=p->Left;}
		    else{pp=p;p=p->Right;}
		}
		if(X<pp->Data)pp->Left=q;
		else pp->Right=q;
	} 
	return BST;
}
Position Find( BinTree BST, ElementType X )  //查询 
{
	BinTree p=BST;
	while(p){
		if(p->Data==X)break;
		else if(X<p->Data)p=p->Left;
		else p=p->Right;
	}
	return p;
}
Position FindMin( BinTree BST )//查找最小值 
{
	BinTree p=BST;
	while(p&&p->Left){          //原来是p->Left&&p 
		p=p->Left; 
	}
	return p;	 
} 
Position FindMax( BinTree BST )   //查找最大值 
{
	BinTree p=BST;
	while(p&&p->Right){
		p=p->Right;
	}
	return p;
}


BinTree Delete( BinTree BST, ElementType X )
{
	BinTree q,qq,pp=NULL,p;//p删除结点,pp删除结点的父亲结点 
	p=BST;
	while(p){               //查找删除结点的位置 
		if(X==p->Data)break;
		else if(X<p->Data){pp=p;p=p->Left;}
		else{pp=p;p=p->Right;}
	}
	if(!p)printf("Not Found\n");
	else{
		if(!p->Left&&!p->Right){   //叶子节点 
			if(!pp){BST=pp;}
			else{
				pp->Left=NULL;
				pp->Right=NULL;
			}
		}
		else if(!p->Right&&p->Left){   //右子树为空,左子树不为空 
			if(!pp){BST=p->Left;}
			else{
				if(pp->Left&&pp->Left->Data==p->Data){pp->Left=p->Left;}  //注意pp->Left可能为空 
				else {pp->Right=p->Left;}
			}
		}
		else if(!p->Left&&p->Right){   //左子树为空,右子树不为空 
			if(!pp){BST=p->Right;}
			else{
				if(pp->Left&&pp->Left->Data==p->Data){pp->Left=p->Right;}
				else {pp->Right=p->Right;}
			}
		}
		else if(p->Left&&p->Right){                       //左右子树都不为空 ,将右子树移动到左子树最大值的右子树。 
			qq=p->Left;
			while(qq->Right)qq=qq->Right;//qq左子树最大的节点 
			qq->Right=p->Right; 
		    if(!pp){BST=p->Left;}
		    else{
				if(pp->Left->Data==p->Data){pp->Left=p->Left;}
				else {pp->Right=p->Left;}
			}
		}
		free(p);
	}
	return BST;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值