BST(C语言)
来源:互联网 发布:javascript复选框全选 编辑:程序博客网 时间:2024/06/11 13:22
/****************************************************
BST.h
***************************************************/
// 定义节点
typedef struct node
{ struct node * parent;
struct node *left;
struct node *right;
int key;
}Node;
void Tree_Insert(Node ** p_node,Node *z);
void Inorder_Tree_Walk(Node * root);
Node * Tree_Search(Node *root,int k);
Node * Tree_Minimum(Node * root);
Node * Tree_Maximum(Node * root);
Node * Tree_Successor(Node * x);
Node * Tree_Predecessor(Node * x);
void Transplant(Node ** p_node,Node * u,Node *v);
void Tree_Delet(Node ** p_node,Node * u);
/*************************************************
BST.c
包括插入节点、删除节点、中序遍历(排序)、查找节点、前继、后继、最小节点、最大节点
************************************************/
#include "BST.h"
#include <stdlib.h>
#include <stdio.h>
//function--插入元素
//p_node-- 指向root的指针的指针
//z--指向插入元素的指针
/******************************
iterative version
*****************************/
void Tree_Insert(Node ** p_node,Node *z)
{ Node *y=NULL;//初始化辅助节点指针
Node *x=*p_node;//节点x指向头节点
//迭代查找待插入节点z的父节点
while(x!=NULL)
{y=x;
if(x->key<z->key)
x=x->right;
else
x=x->left;
}
z->parent=y;// 节点z的parent赋值为y
//分两种情况,来插入z节点
//情况1 为空树
if (y==NULL)
*p_node=z;
//确定z节点应该放在父节点y的左孩子位置还是右海子位置
elseif(y->key<z->key)
y->right=z;
else
y->left=z;
}
//function--插入元素
//p_node-- 指向root的指针的指针
//z--指向插入元素的指针
// iterative version
/*****************************************
recursive version
****************************************/
void Tree_Insert(Node ** p_node,Node *z)
{/*这个if语句是关键,在递归的过程中不断更新z节点parent指针的赋值,直到递归结束*/
if (*p_node!=NULL)
z->parent=*p_node;
/*这个if语句作用是,z节点的父节点指向z,注意与上个if语句区分,他和下面的语句组成了一个选择结构*/
if (*p_node==NULL)
*p_node=z;
elseif(*p_node!=NULL && z->key<(*p_node)->key)
return Tree_Insert(&(*p_node)->left,z);
else
return Tree_Insert(&(*p_node)->right,z);
}
void Inorder_Tree_Walk(Node * root)
{ if( root!=NULL)
{Inorder_Tree_Walk(root->left);
printf("%5d",root->key);
Inorder_Tree_Walk(root->right);
}
}
Node * Tree_Search(Node *root,int k)
{ if (root==NULL||k==root->key)
return root;
if (k<root->key)
return Tree_Search(root->left,k);
else
return Tree_Search(root->right,k);
}
Node * Tree_Minimum(Node * root)
{ while(root->left!=NULL)
root=root->left;
return root;
}
Node * Tree_Maximum(Node * root)
{ while(root->right!=NULL)
root=root->right;
return root;
}
Node * Tree_Successor(Node * x)
{ if (x->right!=NULL)
return Tree_Minimum(x->right);
Node * y=x->parent;
while(y!=NULL &&x==y->right)
{x=y;
y=y->parent;
}
return y;
}
Node * Tree_Predecessor(Node * x)
{ if (x->left!=NULL)
return Tree_Maximum(x->left);
Node * y=x->parent;
while(y!=NULL &&x==y->left)
{ x=y;
y=y->parent;
}
return y;
}
// 这个函数只是将v节点移动到u节点的位置,并没有对u节点作任何处理
//对v节点的left、right指针也没做处理
//是删除函数的一个子程序
void Transplant(Node ** p_node,Node * u,Node *v)
{ if (u->parent==NULL)
*p_node=v;
elseif(u==u->parent->right)
u->parent->right=v;
else
u->parent->left=v;
if(v!=NULL)
v->parent=u->parent;
}
//删除节点函数,感觉最难、最复杂的
// 总共分为三种情况
// 前两种情况比较轻松
// 第三种情况细分为两种情况
/*****************************************************************
第一种,删除节点的后继就是他的右孩子,(注意:那么其右孩子就一定没有左孩子)
让其右孩子,来代替父节点的位置,
右孩子的key比待删除节点的key大,
所以以右孩子为父节点的子数,在局部上是满足二叉树性质的
从整体上来看,原来的子数符合二叉树性质,所以一定满足二叉树性质
右孩子成为父节点过后,需要更新,他的left指针、与parent指针,
类似的与之相关的左孩子与父节点,分别需要更新parent、right指针
***************************************************************/
/****************************************************************
第二种情况与第一种有相似的地方,也有自己的特点
待删节点的右孩子不是其后继的话,一定是以其右节点为根的子树,
最左边的节点,假设是y(注意y一定没有左孩子)
交换y节点和其右孩子
然后再让y替代z节点的位置
更新相关的指针
****************************************************************/
void Tree_Delet(Node ** p_node,Node * u)
{ if(u->left==NULL)
Transplant(p_node,u,u->right);
elseif(u->right==NULL)
Transplant(p_node,u,u->left);
else
{
Node *y=Tree_Minimum(u->right);
if(y!=u->right)
{Transplant(p_node,y,y->right);
y->right=u->right;
y->right->parent=y;
}
Transplant(p_node,u,y);
y->left=u->left;
y->left->parent=y;
}
}
/*****************************************
main() 函数
*****************************************/
#include "BST.h"
#include <stdio.h>
#include <stdlib.h>
/* 可以设计函数来free内存*/
int main(void)
{ Node * p_root;
int key;
p_root=NULL;//初始化为空树
printf("Please enter the key to insert(q to quit)\n");
while(scanf("%d",&key)==1)
{Node *p_node=malloc(sizeof(Node));//动态分配内存
p_node->key=key;
//将头节点指针的位置,传入函数,修改头节点的值,
//也可以把头节点设为文件作用域的变量(不是一个好的选择)
Tree_Insert(&p_root,p_node);
}
printf(" the max vale in the BST:%d\n the minimum value in the BST:%d\n",
Tree_Maximum(p_root)->key,
Tree_Minimum(p_root)->key);
printf("Sorting\n");
Inorder_Tree_Walk(p_root);
putchar('\n');
printf("please enter the key you want delete\n");
while(getchar()!='\n')
continue;
int k;
scanf("%d",&k);
Node * res=Tree_Search(p_root,k);
if(res==NULL)
printf("%d is not in the BST\n",k);
Tree_Delet(&p_root,res);
printf("Now the BST(after sorting)\n");
Inorder_Tree_Walk(p_root);
putchar('\n');
}
- BST(C语言)
- BST树--C语言实现
- 二叉搜索树(BST) ----- C语言
- 二叉查找树(BST)及其C语言实现
- 二叉排序树(BST)的思路及C语言实现
- C语言实现二叉查找树(BST)的基本操作
- <数据结构与算法>二叉搜索树(BST)的基本操作(C语言描述)
- BST
- BST
- BST
- BST
- BST
- BST
- bst
- BST
- BST
- BST
- BST
- 【codevs 1022】覆盖(匈牙利算法)
- Java中==与equals的区别
- 李雅普诺夫稳定性理论
- MUI增加BeeCloud支付集成示例
- 互联网小现象:BAT疯狂投资,网易为何单打独斗?
- BST(C语言)
- AndroidStudio配置百度地图API
- java生成二维码
- jdk安装与环境变量配置
- java.util.AbstractSet学习笔记
- ios Protocol buffer安装
- Hibernate逆向工程(表--->对象)
- 3X3拼图的可解性
- LeetCode No.168 Excel Sheet Column Title