/*
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;
}
[數據結構]二叉查找樹 簡單實現
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.