二叉排序树的基本操作

添加链接描述
这篇文章中介绍了二叉排序树的基本操作 如查找 插入 删除,具体概念上面的博客已经讲的很明白了 至于每行代码的作用 根据自身的理解, 在代码中加入了相关的标记

#include  
#include  
//二叉树的二叉链表结点的结构定义 
typedef struct BiTNode  
{  
    int key;  //结点的数据
    struct BiTNode *lchild, *rchild;//左右孩子指针  
} BiTNode, *BiTree;  
  //递归查找二叉排序树的查找是如何实现的'
 //指针f是指向T的双亲 其初始调用值为NULL
//若查找成功  则指针p执行那个该数据元素的结点 并返回true
//否则指针p指向查找路径上访问的最后一个结点并返回false
int SearchBST(BiTree T,int key,BiTree f,BiTree &p )//查找 
{  
	 if(!T)  {p=f;return 0;}//如果是空树  则返回0
   			else if (key==T->key) {p=T;return 1;}//如果key值就等于根结点的值  指针p指向key值对应的结点 所以这里P=T
    		else if(keykey) SearchBST(T->lchild,key,T,p);//遍历左孩子
               else SearchBST(T->rchild,key,T,p); //遍历右孩子
}
  //在二叉树中插入数据
int InsertBST(BiTree &T,int key)//插入 
{  
	//这个函数是采用递归函数的思想  层层递归  最后新建一个结点 插入值
    if(!T)
    {//如果这颗树是空树,那么给这颗树分配空间  初始化二叉树  
        T=(BiTree)malloc(sizeof(BiTNode)); 
        T->key=key;  
        T->lchild=(T)->rchild=NULL;  
    }  
	//如果要插入的值恰好等于根结点的值 那么就直接退出
    if(key==T->key) return 0;  
	//左右递归
    if(key>T->key) InsertBST(T->rchild,key); 
    else InsertBST(T->lchild,key); 
}  
  //遍历方法  前面的文章中介绍过  这里就不再赘述
void InorderTraverse(BiTree T)//中序遍历
{  
     if(T)//判断这棵树是否为空
     {  //按照LDR的顺序
          InorderTraverse(T->lchild);
          printf("%d ",T->key);
          InorderTraverse(T->rchild);
     }
}
 void Delete(BiTree &p) //删除 
{  
    BiTree q, s;  
    if(!p->lchild &&!p->rchild) //p为叶子节点  
    //如果这个结点没有左右孩子的话  直接将这个结点指针指向空  就代表删除了这个指针
        p = NULL; 
    else if(!p->lchild) //左子树为空,重接右子树
    {  //如果这棵树只有右子树
	//那么删除这个结点后  将它的右子树放到原来的结点的位置 
        q=p;   //将左子数赋值给临时指针q
        p=p->rchild;  //将右孩子放到原来的删除结点的位置
        free(q);  //释放q所指向的空间
    }  
    else if(!p->rchild) //右子树为空,重接左子树
    {  //左子树道理同右子shu
        q=p;  
        p=p->lchild; 
        free(q);  
    }  
    else  //左右子树均不为空  这种情况稍微复杂一点
	//按照中中序排列 将要删除的结点的直接前驱放到被删除结点的位置   
    {  
        q=p;  //现将q指向p所指向的空间
        s=p->lchild; // 临时指针S指向p的左孩子
        while(s->rchild)//一直遍历到s的最后一个右孩子
        {  
            q=s;  //将最后一个右孩子所指向的空间赋给p指针
	//这里的意思就是将p指针左孩子的最后一个右孩子移位到原来p的指针
            s=s->rchild;  
        }  
        p->key=s->key;  //再将这个右孩子的数据域赋值给p
        if(q!=p)//如果q指针与p指针不相等的时  将s的左孩子已到q结点的右孩子的位置
            q->rchild=s->lchild; 
        else  
		//这里的else 是指q与p相等的情况  这个情况有点难理解  
		//就是指s没有经过70行的while循环 也就是s没有右孩子的情况
            q->lchild=s->lchild;//就将s的左孩子重接到q的左孩子的位置
        free(s);  
    }  
}  
int DeleteBST(BiTree &T, int key)//删除 
{  //删除给定值的结点
    if(!T) return 0;
    else  
    {  //判断这个点是否是根结点
	//下面是左右孩子遍历
        if(key==T->key ) Delete(T);  
        else if(keykey)  DeleteBST(T->lchild,key);  
        else  DeleteBST(T->rchild,key);  
    }  
}  
  
int main()  
{  
    int e,n;  
    BiTree T=NULL,f,p; 
    printf("输入长度:");
	scanf("%d",&n); 
	printf("输入元素:");
 	while(n--)
 	{
 		scanf("%d",&e); 
    	InsertBST(T, e);  
 	}
    printf("中序遍历:");  
    InorderTraverse(T);
    printf("\n"); 
    while(1)
	{
		printf("输入要查找元素:");
		scanf("%d",&e); 
		if(SearchBST(T,e,f,p)) printf("找到了\n");
		else printf("没找到\n");
		printf("输入要插入元素:");
		scanf("%d",&e); 
		InsertBST(T,e);
		printf("中序遍历:");  
    	InorderTraverse(T);
    	printf("\n");  
		printf("输入要删除元素:");
		scanf("%d",&e); 
    	DeleteBST(T,e);
    	printf("中序遍历:");  
    	InorderTraverse(T);
    	printf("\n");  
	}
} 


下面是运行的结果

输入长度:6
输入元素:3 0 9 4 7 5
中序遍历:0 3 4 5 7 9 
输入要查找元素:0
找到了
输入要插入元素:6
中序遍历:0 3 4 5 6 7 9 
输入要删除元素:7
中序遍历:0 3 4 5 6 9 
输入要查找元素:9
找到了
输入要插入元素:9
中序遍历:0 3 4 5 6 9 
输入要删除元素:9
中序遍历:0 3 4 5 6 
输入要查找元素:9
没找到
输入要插入元素:^C

你可能感兴趣的:(学生)