您的位置:首页 > 其它

二叉查找树带父节点指针的创建,销毁,查找,删除,插入,找前驱后继,找最小值最大值(递归和非递归的实现)

2014-04-09 17:02 1061 查看
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<time.h>

typedef int  bool ;
#define true  1
#define false 0

#define SWAP(x,y,t) ((t=x),(x=y),(y=t))

#define INT
#ifdef  CHAR
typedef char DataType;
#else
typedef int DataType ;
#endif

typedef struct Node
{
DataType data;
struct Node *lchild;
struct Node *rchild;
struct Node *parent;
} BSTNode ,* pBSTNode ;

void InsertBST(pBSTNode *root,DataType x);
bool Delete_x_BST(pBSTNode *root,DataType x);   //两个都是删除节点元素但是一个是提供要删除元素的指针,另一个是要删除的元素
void DeleteBST(pBSTNode *root,pBSTNode p ,DataType *x);
pBSTNode SearchBST(pBSTNode root ,DataType x);

pBSTNode SearchMaxBST(pBSTNode root);
pBSTNode SearchMaxBST2(pBSTNode root);
pBSTNode SearchMinBST(pBSTNode root);
pBSTNode SearchMinBST2(pBSTNode root);

pBSTNode SearchPredecessor(pBSTNode p);
pBSTNode SearchSuccessor(pBSTNode p);

pBSTNode CreateBST();
void Visit(DataType data);
void DestroyBST( pBSTNode root);

void PreOrderTraverseBST(pBSTNode root);
void InOrderTraverseBST(pBSTNode root);

void InsertBST(pBSTNode *root,DataType x)
{

pBSTNode ptr=(pBSTNode) malloc(sizeof(BSTNode) ) ;
ptr->data=x;
ptr->lchild=NULL;
ptr->rchild=NULL;
ptr->parent=NULL;
if(! *root)
{
*root =ptr;
return ;
}

pBSTNode cur=*root;
pBSTNode pre=cur;
while ( cur)
{
pre=cur;
if(cur->data<x )
{
cur=cur->rchild;
}
//	else if(p->data ==x)
//	{
//		printf(" insert the %d is not illegal,BST mustn't have the same key\n ");
//		exit(-1);
//	}
else
{
cur=cur->lchild;
}

}

if( pre->data <x)
{
pre->rchild=ptr;
ptr->parent=pre;
}
else
{
pre->lchild=ptr;
ptr->parent=pre;
}

}
/*
*
*根据某个节点的指针,删除某个元素,并传回它的值
*
* */
void DeleteBST(pBSTNode *root,pBSTNode p ,DataType *x)
{
if( !p)
{
printf("the list is null\n ");
exit(-1);
}
else
{
*x=p->data;
if(p->lchild==NULL && p->rchild==NULL) //待删除节点为叶子节点时
{
if( p->parent ==NULL)  //只有一个节点时,根节点发生变化 
{
*root=NULL;
}
else
{
if(p==p->parent->lchild)
{
p->parent->lchild=NULL;
}
else if(p==p->parent->rchild)
{
p->parent->rchild=NULL;
}
}

free(p) ;
}

else if(p->lchild==NULL&& p->rchild!=NULL)  //待删除节点左子树为空,右子树不为空
{
if(p->parent==NULL) //待删除节点为根节点时
{
*root=p->rchild;
p->rchild->parent=NULL;
}
else
{
if(p==p->parent->lchild)
{
p->parent->lchild=p->rchild;
p->rchild->parent=p->parent;
}
else
{
p->parent->rchild=p->rchild;
p->rchild->parent=p->parent;
}
}
free(p);

}

else if( p->lchild!=NULL && p->rchild==NULL)  //待删除节点左子树不为空,右子树为空
{
if(p->parent==NULL)  //待删除节点为根节点时
{
*root=p->lchild;
p->lchild->parent=NULL;
}
else
{
if(p==p->parent->lchild)
{
p->parent->lchild=p->lchild;
p->lchild->parent=p->parent;
}
else
{
p->parent->rchild=p->lchild;
p->lchild->parent=p->parent;
}
}
free(p);

}

else  //左右子树都存在的时候
{
pBSTNode q=SearchSuccessor(p); //或者是该节点的前驱,由于前驱节点或者后继节点为左子树的最大节点或者为右子树的最小节点
//则前驱或者后继节点的度必为0或1,由于这个结论我们就可以递归调用Delete_x_BST
DataType temp;
SWAP(p->data,q->data,temp) ;

if(q->lchild==NULL && q->rchild==NULL) //待删除节点为叶子节点时
{
if( q->parent ==NULL)  //只有一个节点时,根节点发生变化 
{
*root=NULL;
}
else
{
if(q==q->parent->lchild)
{
q->parent->lchild=NULL;
}
else
{
q->parent->rchild=NULL;
}

}
free(q) ;
}

else if(q->lchild==NULL&& q->rchild!=NULL)  //待删除节点左子树为空,右子树不为空
{
if(q->parent==NULL) //待删除节点为根节点时
{
*root=q->rchild;
q->rchild->parent=NULL;
}
else
{
if(q==q->parent->lchild)
{
q->parent->lchild=q->rchild;
q->rchild->parent=q->parent;
}
else
{
q->parent->rchild=q->rchild;
q->rchild->parent=q->parent;
}
}
free(q) ;

}

else if( q->lchild!=NULL && q->rchild==NULL)  //待删除节点左子树不为空,右子树为空
{
if(q->parent==NULL)  //待删除节点为根节点时
{
*root=q->lchild;
q->lchild->parent=NULL;
}
else
{
if(q==q->parent->lchild)
{
q->parent->lchild=q->lchild;
q->lchild->parent=q->parent;
}
else
{
q->parent->rchild=q->lchild;
q->lchild->parent=q->parent;
}
}
free(q) ;
}

}

}

}
/*
*
*删除关键字为x的节点
*
* */
bool Delete_x_BST(pBSTNode *root,DataType x)
{
pBSTNode p=SearchBST(*root ,x) ;
if(!p)
{
printf("没有值为x的节点或者二叉树为空(不过二叉树为空也是没有值为x的节点的情况)\n");
return false;
}
else
{

if(p->lchild==NULL && p->rchild==NULL) //待删除节点为叶子节点时
{
if( p->parent ==NULL)  //只有一个节点时,根节点发生变化 
{
*root=NULL;
}
else
{
if(p==p->parent->lchild)
{
p->parent->lchild=NULL;
}
else if(p==p->parent->rchild)
{
p->parent->rchild=NULL;
}
}

free(p) ;
}

else if(p->lchild==NULL&& p->rchild!=NULL)  //待删除节点左子树为空,右子树不为空
{
if(p->parent==NULL) //待删除节点为根节点时
{
*root=p->rchild;
p->rchild->parent=NULL;
}
else
{
if(p==p->parent->lchild)
{
p->parent->lchild=p->rchild;
p->rchild->parent=p->parent;
}
else
{
p->parent->rchild=p->rchild;
p->rchild->parent=p->parent;
}
}
free(p);

}

else if( p->lchild!=NULL && p->rchild==NULL)  //待删除节点左子树不为空,右子树为空
{
if(p->parent==NULL)  //待删除节点为根节点时
{
*root=p->lchild;
p->lchild->parent=NULL;
}
else
{
if(p==p->parent->lchild)
{
p->parent->lchild=p->lchild;
p->lchild->parent=p->parent;
}
else
{
p->parent->rchild=p->lchild;
p->lchild->parent=p->parent;
}
}
free(p);

}

else  //左右子树都存在的时候
{
pBSTNode q=SearchSuccessor(p); //或者是该节点的前驱,由于前驱节点或者后继节点为左子树的最大节点或者为右子树的最小节点
//则前驱或者后继节点的度必为0或1,由于这个结论我们就可以递归调用Delete_x_BST
DataType temp;
SWAP(p->data,q->data,temp) ;
//Delete_x_BST( &*root ,q->data); 但是递归调用会出现问题,如果节点元素相同时,但是带有卫星数据时,删除的数据不是我们要删除的数据

if(q->lchild==NULL && q->rchild==NULL) //待删除节点为叶子节点时
{
if( q->parent ==NULL)  //只有一个节点时,根节点发生变化 
{
*root=NULL;
}
else
{
if(q==q->parent->lchild)
{
q->parent->lchild=NULL;
}
else
{
q->parent->rchild=NULL;
}

}
free(q) ;
}

else if(q->lchild==NULL&& q->rchild!=NULL)  //待删除节点左子树为空,右子树不为空
{
if(q->parent==NULL) //待删除节点为根节点时
{
*root=q->rchild;
q->rchild->parent=NULL;
}
else
{
if(q==q->parent->lchild)
{
q->parent->lchild=q->rchild;
q->rchild->parent=q->parent;
}
else
{
q->parent->rchild=q->rchild;
q->rchild->parent=q->parent;
}
}
free(q) ;

}

else if( q->lchild!=NULL && q->rchild==NULL)  //待删除节点左子树不为空,右子树为空
{
if(q->parent==NULL)  //待删除节点为根节点时
{
*root=q->lchild;
q->lchild->parent=NULL;
}
else
{
if(q==q->parent->lchild)
{
q->parent->lchild=q->lchild;
q->lchild->parent=q->parent;
}
else
{
q->parent->rchild=q->lchild;
q->lchild->parent=q->parent;
}
}
free(q) ;
}

}

return true ;
}

}

pBSTNode SearchBST(pBSTNode root ,DataType x)
{
if(! root)
return NULL;
if(root->data==x)
return root;
else if(root->data < x )
return SearchBST(root->rchild , x);
else
return SearchBST(root->lchild , x);

}

/*
*查找二叉查找树最大值的递归形式
*
* */

pBSTNode SearchMaxBST(pBSTNode root)
{
if(!root)
return NULL;
else if(root->rchild==NULL)
return root ;
else
return SearchMaxBST(root->rchild) ;
}

/*
*
*查找二叉查找树的最大值 非递归形式
*
* */
pBSTNode SearchMaxBST2(pBSTNode root)
{
if( !root)
return NULL;
else
{
pBSTNode cur=root;
pBSTNode pre=cur;
while(cur)
{
pre=cur;
cur=cur->rchild;
}
return pre;

}
}

/*
*查找二叉查找树最小值递归形式
*
* */
pBSTNode SearchMinBST(pBSTNode root)
{
if(!root)
return NULL;
else if (root->lchild==NULL)
return root;
else return SearchMinBST(root->lchild) ;
}

/*
*查找二叉查找树最小值非递归形式
*
* */

pBSTNode SearchMinBST2(pBSTNode root)
{
if(!root)
return NULL;
else
{
pBSTNode cur=root;
pBSTNode pre=cur;
while( cur)
{
pre=cur;
cur=cur->lchild;
}
return pre;

}
}

/*
*
*查找某个节点的前驱
*
* */

pBSTNode SearchPredecessor(pBSTNode p)
{
if(!p)
{
printf("the input is null.don't have the Predecessor\n ") ;
exit(-1);
}
else
{
if( p->lchild==NULL)
{
pBSTNode pre=p->parent; //父节点
while(pre)
{
if(pre->rchild==p) //如果父节点是爷爷节点的有孩子则爷爷节点就是前驱
{
return pre;
}
else
{
p=pre;
pre=pre->parent;
}
}
return NULL;
}
else
{
return SearchMaxBST(p->lchild) ; //如果左子树存在,前驱为左子树的最大值节点
}

}
}

pBSTNode SearchSuccessor(pBSTNode p)
{
if( !p)
{
printf("the input is null. don't have the predecessor\n");
exit(-1);
}
else
{
if( p->rchild ==NULL)
{
pBSTNode pre=p->parent;
while( pre)
{
if(pre->lchild==p)
{
return pre;
}
else
{
p=pre;
pre=pre->parent;
}
}
return NULL;
}

else
{
return SearchMinBST(p->rchild);
}
}

}

/*
pBSTNode CreateBST()
{
int i;
int a[10];
pBSTNode T=NULL;
srand( (unsigned int) time(NULL) ) ;
for ( i=0 ;i<10 ;i++)
a[i]=rand()%30;
printf("the original data:\n");

for ( i=0 ;i<10 ;i++)
printf("%d ",a[i]);
printf("\n");
for( i=0 ;i<10 ;i++)
InsertBST(&T ,a[i]) ;
return T;
}
*/

pBSTNode CreateBST()
{
int i;
int a[8]={4,7,8,2,3,5,6,9};
pBSTNode T=NULL;
printf("the original data:\n");

for ( i=0 ;i<8 ;i++)
printf("%d ",a[i]);
printf("\n");
for( i=0 ;i<8 ;i++)
InsertBST(&T ,a[i]) ;
return T;
}

void Visit(DataType data)
{
printf(" %d ",data) ;
}

void PreOrderTraverseBST(pBSTNode root)
{
if(!root)
return ;
else
{
Visit(root->data);
PreOrderTraverseBST(root->lchild) ;
PreOrderTraverseBST(root->rchild) ;
}
}

void InOrderTraverseBST(pBSTNode root)
{
if(!root)
return ;
else
{
InOrderTraverseBST(root->lchild) ;
Visit(root->data) ;
InOrderTraverseBST(root->rchild) ;
}
}

void DestroyBST( pBSTNode root)
{
if( !root)
return ;
else
{
DestroyBST( root->lchild) ;
DestroyBST( root->rchild) ;
free(root) ;
}
}

int main()
{
pBSTNode T=CreateBST() ;
PreOrderTraverseBST(T) ;
printf("\n");
InOrderTraverseBST(T) ;
printf("\n");
int i=2;
pBSTNode p=SearchBST( T ,i) ;
if( p)
{
printf("\nyou search the %d .Success!\n",i);
printf("\nso you receive the poniter,we can delete it\n");
DataType x;
DeleteBST(&T,p,&x);
printf("要删除的元素是%d \n",x);
printf("after delete the %d\n",x);
InOrderTraverseBST(T) ;
printf("\n");
}
else
printf("\nyou can't search the %d.\n",i) ;
pBSTNode predecessor=SearchPredecessor(p) ;
if( predecessor)
printf("\nthe predecessor is %d.\n",predecessor->data);
else
printf("\n%d don't have the predecessor\n",i) ;

pBSTNode succesor=SearchSuccessor(p) ;
if( succesor)
printf(" \nthe successor is %d.\n" ,succesor->data);
else
printf(" \n%d don't have the successor\n",i ) ;

DataType del_num=5;
if( Delete_x_BST(&T ,del_num) )
{
printf("要删除的元素是%d \n",del_num);
printf("after delete the %d\n",del_num);
InOrderTraverseBST(T);
printf("\n");
}

p=SearchMaxBST(T) ;
if (p)
printf("the BST's MAX 递归形式 is %d\n", p->data) ;

p=SearchMaxBST2(T) ;
if (p)
printf("the BST's MAX 非递归形式 is %d\n" , p->data) ;
p=SearchMinBST(T) ;
if(p)
printf("the BST's Min 递归形式 is %d\n" , p->data) ;

p=SearchMinBST2(T) ;
if (p)
printf("the BST's Min 非递归形式 is %d\n" , p->data) ;

DestroyBST(T);
return 1;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐