LeeBlog

导航

二叉排序树 插入 删除 遍历

这两天要弄数据结构考试,就在写二叉排序树

二叉排序树总共三个操作:插入,查找,删除,遍历;

先提醒对于插入,删除等要改变这棵树的操作都要用二维指针,否则不能改变,而遍历( 打印 ),查找( 这里的查找因为要为删除服务,所以用了二维指针,其实纯粹的查找是不需要的 )不需改变他的值,所以不用二维指针

插入:小的往左边放,大的往右边放,相等的直接不要,然后递归处理就可以了。

查找:如果查找的值等于当前节点,则返回当前节点,若查找的值比当前节点小则在当前节点的左子树中去找,若比当前节点大,则在当前右子树中去找,若差找不成功,返回NULL;

删除:这个是最令我头痛的,开始按数据结构上的来,一直改不对,就一直在找事不是指针的问题,改了一晚上没结果,最后看到一份文档把删除节点的思想看懂了才写出来的。大意如下:

  总共分为两种情况,假设要删除的节点p,一种是有左子树,另一种是没左子树(包括p没孩子的那一种);当有左子树时,就在p的左子树中找到最右边的那一个(即p左子树中最大的那一个)r,用r的值取代p的值,这样就把p原来的值给覆盖了,那么p也就不存在了,这样还多出一个节点r,怎么办呢,当然是删除啊,但是r可能还有左子树,若r还有左子树就用r的左子树取代r的位子就行了。另一种情况没有左子树那么就用p的右子树取代他的位置,然后再删掉他原来的节点就可以了( p没孩子的情况也适用这种情况 );

遍历:直接一个中序遍历就可以了;

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
typedef struct Node
{
	int data;
	struct Node *lc,*rc;
}node,*Link;
void insert( Link *L,int n )
{
	if( *L == NULL )
	{
		( *L ) = new node;//若找到插入位置,则新申请节点
		( *L ) -> lc = ( *L ) -> rc = NULL;
		( *L ) -> data = n;
	}
	else
	{
		if( n == ( *L ) -> data )//若n与当前节点的值相等,则不需插入了
			return ;
		else if( n < ( *L ) -> data )//若n比当前节点的值小,则往当前节点的左子树插
			insert( &( *L ) -> lc,n );
		else//若n比当前节点的值大,则往当前节点的右子树插
			insert( &( *L ) -> rc,n );
	}
}
Link *Search( Link *L,int x )
{
	Link p;
	if( *L )
	{
		if( ( *L ) -> data == x )//若找到节点,则返回当前节点
			return L;
		if( x < ( *L ) -> data )//若x比当前节点的值小,则在当前节点的左子树中去找
			return Search( &( *L ) -> lc, x );
		else//若x比当前节点的值大,则在当前节点的右子树中去找
			return Search( &( *L ) -> rc, x );
	}
	return NULL;
}
void Delete( Link *p )
{
	if( ( *p ) -> lc  )//若有左子树
	{
		Link pre = ( *p ) -> lc;
		Link r = ( *p ) -> lc;
		while( r -> rc )//去查找左子树中最右边的节点
			pre = r, r = r -> rc;
		( *p ) -> data = r -> data;//用左子树中最右边的节点的值覆盖要删除的节点
		if( pre != r )//若p左子树有右节点
			pre -> rc = r -> lc;
		else//若p左子树没有右节点
			( *p ) -> lc = r -> lc;
		free( r );//释放节点
	}
	else//若无左子树
	{
		Link q = ( *p );
		*p = ( *p ) -> rc;
		free( q );
		q = NULL;
	}
}
void Print( Link L )
{
	if( L )//中序遍历
	{
		Print( L -> lc );
		printf( "%d ",L -> data );
		Print( L -> rc );
	}
}
int main(  )
{
	Link L = NULL;
	int n,x;
	while( 1 )
	{
		printf( "1  插入  2 中序遍历 3 查找  4 删除\n" );
		char ch;
		ch = getch(  );
		if( ch == '1' )//插入
		{
			printf( "请输入n:" );
			scanf( "%d",&n );
			insert( &L,n );
		}
		else if( ch == '2' )//中序遍历
		{
			if( L == NULL )
				printf( "没有节点\n" );
			else
				Print( L );
				
		}
		else if( ch == '3' )//查找
		{
			if( L == NULL )
				printf( "没有节点\n" );
			else
			{
				printf( "请输入要查找的数x:" );
				scanf( "%d",&x );
				Link *p;
				p = Search( &L,x );
				if( p )
					printf( "查找成功\n" );
				else
					printf( "没有%d这个节点\n",x );
			}
		}
		else if( ch == '4' )//删除
		{
			printf( "请输入您要删除的数x:" );
			scanf( "%d",&x );
			Link *p;
			p = Search( &L,x );//先看有没有这个节点
			if( !p )
				printf( "没有这个数" );
			else
			{
				Delete( p ); //若有则进行删除操作
				printf( "删除成功\n" );
			}
		}
		printf( "\nOK" );
		getch();
		system( "cls" );
	}
	return 0;
}
//+-+*3##*x##x##x##/1##x##5##

posted on 2011-06-13 00:06  LeeBlog  阅读(1689)  评论(0编辑  收藏  举报