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