二叉数

         二叉树,也是数的一种,不过这种数每次分下来都有两个儿子指针,并且小于这个数的全部在左子树上,大于的再右子树上。这样进行一次中序遍历的结果也就是从小到大排序的结果。当然在而叉树上进行查找速度也是非常快的。下面就是一些常规的二叉树的一些操作。插入,删除之类的操作。也就是通过这些操作。来加强一下对二叉树的一些解。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 100

typedef struct node {
    //二叉树有三个指针,左右儿子指针和父结点指针
   struct node *prt;
   struct node *left;
   struct node *right;
   int key;
}Tree;

Tree* creat_node(int num)
{
    //创建一个结点。每次创建的时候三个指针都是空值
    Tree *new;
    new = (Tree*)malloc(sizeof(Tree));
    new->prt = NULL;
    new->left = NULL;
    new->right = NULL;
    new->key = num;
    return new;
}

Tree* tree_insert(Tree* root,int num)
{
    //插入操作,需要两个指针,一个指向插入数据,一个需要记录插入数据的父结点
    Tree *new,*per,*head;
    per = NULL;
    head = root;
    new = creat_node(num);

    if(root==NULL)
	return new;

    while(root!=NULL){
	per = root;
	if(root->key > new->key)
	   root = root->left;
  	else
	   root = root->right;
   }
   if(per->key>new->key)
	per->left = new;
   else
	per->right = new;
   new->prt = per;
   return head;
} 

Tree* tree_max(Tree* root)
{
    //一棵树中的最大值 在求前趋和后继的时候用的上
    while(root->right!=NULL)
	root = root->right;
    return root;
}

Tree* tree_min(Tree* root)
{
    while(root->left!=NULL)
	root = root->left;
    return root;
}

Tree* tree_per(Tree* root,Tree* node)
{
    //求一棵树的前趋,也就是比这个数小的数中最大的一个 如果是最小的数 没有前趋
    Tree* cur;
    cur = NULL;
    if(node==tree_min(root))
	return NULL;
    if(node->left!=NULL)
	return tree_max(node->left);
    while(node->prt!=NULL&&node->prt->right!=node){
	cur = node;
	node = node->prt;
    }
    return node->prt;
}

Tree* tree_next(Tree* root,Tree* node)
{
    //后继,比这个数大的数中最小的一个。如果是最大的数 没有后继
    Tree* per;
    per = NULL;
    if(node==tree_max(root))
	return NULL;
    if(node->right!=NULL)
	return tree_min(node->right);
    while(node->prt!=NULL&&node->prt->left!=node){
	per = node;
	node = node->prt;
    }
    return node->prt;
}

Tree* tree_search(Tree* root,const int key)
{
    //查找一个值,如果找到返回结点指针
    //也可以用递归来写
    while(root!=NULL){
	if(key == root->key)
	   return root;
	else if(key < root->key)
	   root = root->left;
	else
	   root = root->right;
    }
    return (Tree*)NULL;
}

Tree* tree_delete(Tree* root,Tree* node)
{
    //删除结点node.有两种情况
    //情况一:有一个儿子结点或者没有儿子结点  就让父结点指向儿子结点即可
    //情况二:有两个儿子结点,就找到这个数的后继,来替换这个结点的值,再把后继删除即可
    Tree *z,*y;

    if(node->left==NULL||node->right==NULL)
	y = node;
    else
	y = tree_next(root,node);

    if(y->left!=NULL)
	z = y->left;
    else
	z = y->right;

   if(z!=NULL)
        z->prt = y->prt;
   if(y->prt->left==y)
	y->prt->left = z;
   else
	y->prt->right = z;
   if(y!=node)
	node->key = y->key;
}

void tree_print(Tree* root)
{
    //中序遍历一棵树
    if(root!=NULL){
       	tree_print(root->left);
	printf("%-3d",root->key);
	tree_print(root->right);
   }
}


int main()
{
    Tree *root;
    int n,i,key;
    root = NULL;

    scanf("%d",&n);
    for(i=1;i<=n;i++){
	scanf("%d",&key);
	root=tree_insert(root,key);
    }
    tree_print(root);

    Tree *result,*rs;
    result = NULL;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
	Tree *before,*next;
	before = NULL;
	next = NULL;
	scanf("%d",&key);
	result=tree_search(root,key);
        if(rs=result->left)
	   printf("left :%d\n",rs->key);
	if(rs=result->right)
	   printf("right: %d\n",rs->key);
	if(rs=result->prt)
	   printf("parent: %d\n",rs->key);
	before = tree_per(root,result);
	if(before!=NULL)
	   printf("Before : %d\n",before->key);
	next = tree_next(root,result);
	if(next!=NULL)
	   printf("Next : %d\n",next->key);
	tree_delete(root,result);
	tree_print(root);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值