/*
Name:二叉查找树 简单实现
Actor:HT
Time:2015年10月11日
Error Reporte: 1.子函数中给指针赋予新的地址的时候,不要忘记引用...
2.找前驱,删点的时候,一定要搞清楚逻辑
*/
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#define N 10010
struct DFT
{
int key;
DFT* p;
DFT* left;
DFT* right;
};
void tinsert(DFT* &root,int a) //BUG点 由于是malloc 别忘了引用
{
int i, j;
DFT *fin = root, *t = NULL;
for (;;)
{
if (root == NULL) //根节点
{
root = (DFT*)malloc(sizeof(DFT));
root->key = a;
root->left = NULL;
root->right = NULL;
root->p = t;
root->key = a;
break;
}
else if (a <= fin->key) //左
{
if (fin->left != NULL)
{
fin = fin->left;
}
else
{
fin->left = (DFT*)malloc(sizeof(DFT));
fin->left->key = a;
fin->left->left = NULL;
fin->left->right = NULL;
fin->left->p = fin;
break;
}
}
else if (a > fin->key) //右
{
if (fin->right != NULL)
{
fin = fin->right;
}
else
{
fin->right = (DFT*)malloc(sizeof(DFT));
fin->right->key = a;
fin->right->left = NULL;
fin->right->right = NULL;
fin->right->p = fin;
break;
}
}
}
}
DFT* tsuccessor(DFT* &root, int a)
{
DFT* p = root;
for (;;) //查找点
{
if (p == NULL)
{
printf("No point\n");
return NULL;
}
if (p->key == a)
break;
else if (a < p->key)
p = p->left;
else if (a > p->key)
p = p->right;
}
if (p->right != NULL) //找最大右儿子
{
p = p->right;
D: if (p->left != NULL)
{
p = p->left;
goto D;
}
return p;
}
else if (p->p != root->p) //最小的祖上
{
K: if (p == p->p->left)
return p->p;
else
{
p = p->p;
if (p->p != root->p)
goto K;
else
{
printf("No successor\n");
return NULL;
}
}
}
else
{
//printf("No successor\n");
return NULL;
}
}
DFT* tpredecessor(DFT* &root, int a)
{
DFT* p = root;
for (;;) //查找点
{
if (p == NULL)
{
printf("No point\n");
return NULL;
}
if (p->key == a)
break;
else if (a < p->key)
p = p->left;
else if (a > p->key)
p = p->right;
}
if (p->left != NULL)
{
p = p->left;
D: if (p->right != NULL)
{
p = p->right;
goto D;
}
return p;
}
else if (p->p != root->p)
{
K: if (p == p->p->right)
return p->p;
else
{
p = p->p;
if (p->p != root->p)
goto K;
else
{
printf("No predecessor\n");
return NULL;
}
}
}
else
{
//printf("No predecessor\n");
return NULL;
}
}
void tdelete(DFT*& root ,int a)
{
DFT* p = root;
for (;;) //查找点
{
if (p == NULL)
{
printf("No point\n");
return;
}
if (p->key == a)
break;
else if (a < p->key)
p = p->left;
else if (a > p->key)
p = p->right;
}
if (p->left == NULL&&p->right == NULL) //无后
{
if (p->p != NULL)
{
if (p->p->left == p)
{
p->p->left = NULL;
free(p);
}
else if (p->p->right == p)
{
p->p->right = NULL;
free(p);
}
}
else
free(p);
}
else if (p->left != NULL && p->right == NULL) //有左儿子
{
if (p->p != NULL)
{
if (p->p->left == p)
{
p->p->left = p->left;
p->left->p = p->p;
free(p);
}
else if (p->p->right == p)
{
p->p->right = p->left;
p->left->p = p->p;
free(p);
}
}
else
{
if (p == root)
{
root = p->left;
root->p = NULL; //BUG点
free(p);
}
}
}
else if (p->left == NULL && p->right != NULL) //有右儿子
{
if (p->p != NULL)
{
if (p->p->left == p)
{
p->p->left = p->right;
p->right->p = p->p;
free(p);
}
else if (p->p->right == p)
{
p->p->right = p->right;
p->right->p = p->p;
free(p);
}
}
else
{
if (p == root)
{
root = p->right;
root->p = NULL; //BUG点
free(p);
}
}
}
else //俩儿子 删除改点的后继点,然后用后继点的值代替该点
{
DFT* tp = tsuccessor(p, p->key);
int ttp = tp->key;
tdelete(root,tp->key);
p->key = ttp;
}
}
void twalk(DFT * point)
{
if (point->left != NULL)
twalk(point->left);
printf("%d ", point->key);
if (point->right != NULL)
twalk(point->right);
}
void tdestory(DFT * point)
{
if (point->left != NULL)
tdestory(point->left);
if (point->right != NULL)
tdestory(point->right);
free(point);
}
int main()
{
int i, j;
DFT *root = NULL;
//插入 遍历部分测试
int a[7] = { 5, 3, 8, 4, 2, 9, 7};
for (i = 0; i < 7; i++)
{
tinsert(root, a[i]);
}
twalk(root);
printf("\n");
//前驱 后继部分测试
//DFT* tt;
//int ttt;
//for (i = 0; i < 7; i++)
//{
// scanf("%d", &ttt);
// tt = tsuccessor(root, ttt);
// if (tt != NULL)printf("%d's successor is %d\n", ttt, tt->key);
//}
//删除部分测试
//DFT* tt;
//int ttt;
//for (i = 0; i < 7; i++)
//{
// scanf("%d", &ttt);
// tdelete(root, ttt);
// twalk(root);
// printf("\n");
//}
tdestory(root);
system("pause");
return 0;
}
[数据结构]二叉查找树 简单实现
最新推荐文章于 2024-05-23 17:47:28 发布