在此以链式存储的方式实现,为平衡树做铺垫,实现搜索树的:插入(构建)、删除、查找、遍历操作,在此以纯C语言编写(以后有上机考试为纯C,在此适应),使用黑盒测试进行了少量数据验证,欢迎指正。
Code(C)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define null NULL
#define bool int
const int true = 1;
const int false = 0;
typedef struct BTNode {
char data;
struct BTNode *lchild, *rchild;
} BTNode;
/*
* 插入节点
*/
void insertBTNode(BTNode **root, char val)
{
BTNode *node = null;
BTNode *pt = null, *pre = null;
if (!(*root)) {
node = (BTNode*)malloc(sizeof(BTNode));
node->data = val;
node->lchild = node->rchild = null;
*root = node;
return ;
}
pt = *root;
while (pt) {
pre = pt;
if (val == pt->data)
return ;
if (val > pt->data)
pt = pt->rchild;
else
pt = pt->lchild;
}
node = (BTNode*)malloc(sizeof(BTNode));
node->data = val;
node->lchild = node->rchild = null;
if (val > pre->data)
pre->rchild = node;
else
pre->lchild = node;
}
/*
* 查找某节点值
*/
bool searchInTree(BTNode *root, char val)
{
BTNode *pt = root;
while (pt) {
if (pt->data == val)
return true;
if (val > pt->data)
pt = pt->rchild;
else
pt = pt->lchild;
}
return false;
}
/*
* 中序遍历输出
*/
void inorder(const BTNode *node)
{
if (node == null)
return ;
inorder(node->lchild);
printf("%c ", node->data);
inorder(node->rchild);
}
/*
* 删除操作
*/
int deleteNode(BTNode **root, BTNode *pre, BTNode *pt)
{
BTNode *forpt = null, *prept = null;
if (!pt->lchild && !pt->rchild) //没有左子树也没有右子树,妥妥的叶子节点
{
if (!pre) { //要删除的是根节点
*root = null;
} else {
//删除非根节点
if (pt->data > pre->data)
pre->rchild = null;
else
pre->lchild = null;
}
free(pt);
//pt = null; //这不多余不?
}
else if (!pt->lchild && pt->rchild) //没有左子树,存在右子树
{
if (!pre) { //要删除的是根节点
*root = pt->rchild;
} else {
//删除非根节点
if (pt->data > pre->data)
pre->rchild = pt->rchild;
else
pre->lchild = pt->rchild;
}
free(pt);
}
else if (pt->lchild && !pt->rchild) //有左子树,没有右子树
{
if (!pre) { //要删除的是根节点
*root = pt->lchild;
} else {
//删除非根节点
if (pt->data > pre->data)
pre->rchild = pt->lchild;
else
pre->lchild = pt->lchild;
}
free(pt);
}
else if (pt->lchild && pt->rchild) //两边的子树都存在
{
//去找左子树的最右节点
forpt = pt->lchild;
prept = pt;
while (forpt->lchild || forpt->rchild) {
prept = forpt;
if (forpt->rchild)
forpt = forpt->rchild;
else
forpt = forpt->lchild;
}
if (forpt->data > prept->data)
prept->rchild = null;
else
prept->lchild = null;
pt->data = forpt->data;
free(forpt);
}
}
/*
* 删除树节点
*/
int deleteBTNode(BTNode **root, char val)
{
BTNode *pt = *root, *pre = null;
int status = 0;
while (pt) {
if (val == pt->data) {
//找到了删除节点,对要删除的节点进行种类判定(4种不同的删除方式-叶子、左右子树存在一个、左右子树都存在、左右子树都不存在)
deleteNode(root, pre, pt);
status = 1;
break;
}
pre = pt;
if (val > pt->data)
pt = pt->rchild;
else
pt = pt->lchild;
}
return status;
}
/*
* 纯C语言输出char很麻烦,自定义输出
*/
int scanfAInt()
{
int n;
scanf("%d", &n);
getchar();
return n;
}
char scanfAChar()
{
char c;
scanf("%c", &c);
getchar();
return c;
}
int main()
{
BTNode *root = null;
int n, i;
char val;
bool flag = false;
n = scanfAInt();
for (i = 0; i < n; i++) {
val = scanfAChar();
insertBTNode(&root, val);
}
inorder(root);
printf("\n");
if (!deleteBTNode(&root, 'g')) {
printf("No the val!\n");
} else {
printf("Ans:");
inorder(root);
printf("\n");
}
return 0;
}
测试数据
/* 测试数据
1
g
//
2
g a
//a
5
g d a b e
//a b d e
3
g a j
//a j
9
g d a b e f l k m
//a b d e f k l m
2
g j
//j
6
g j h i l k
//h i j k l
8
o g c a d k h m
//a c d h k m o
11
u y o q g c a d k h m
//a c d h k m o q u y
4
o g c k
//c k o
3
o g c
//c o
3
o g k
//k o
*/