二叉排序树

1.和次优查找树相对,二叉排序树是一种动态树表。

2.二叉排序树的结构通常不是一次生成的,而是在查找过程中,当树中不存在关键字等于给定值的结点时再进行插入。

3.含有n条记录的二叉查找树平均查找长度:

4.实现:

二叉排序树的查找

 1 int SearchBST(BTree T, BTree* P, int key)//非递归查找二叉排序树
 2 {
 3     BTree Pre = NULL;
 4     (*P) = T;
 5     while (*P)
 6     {
 7         if ((*P)->data == key)
 8         {
 9             return 1;
10         }
11         else if ((*P)->data < key)//右子树
12         {
13             Pre = (*P);
14             (*P) = (*P)->Rchild;
15         }
16         else//左子树
17         {
18             Pre = (*P);
19             (*P) = (*P)->Lchild;
20         }
21     }
22     (*P) = Pre;
23     return 0;
24 }

二叉排序树的插入

 1 void InsertBST(BTree* T, int key)
 2 {
 3     BTree P = NULL, S = NULL;
 4     if (!SearchBST((*T), &P, key))
 5     {
 6         BTree S = (BTree)calloc(1, sizeof(BTNode));
 7         S->data = key;
 8         S->Lchild = S->Rchild = NULL;
 9         if (!P)//二叉排序树T中一个记录都没有
10         {
11             (*T) = S;
12         }
13         else if (P->data < key)
14         {
15             P->Rchild = S;
16         }
17         else
18         {
19             P->Lchild = S;
20         }
21     }
22 }

二叉排序树的删除

实现步骤:

①查找关键字等于key的结点,保存指向待删结点的指针P和其双亲结点F;

②当指针P为空,则不存在该记录、无需删除;

③当P没有左孩子且其双亲结点F为空,说明二叉排序树中只有待删除的结点,直接置空树;

④当P没有左孩子且其双亲结点F存在,若P是F的左孩子时,令F的左孩子指向P的右孩子;若P是F的右孩子时,令F的右孩子指向P的右孩子;

⑤当P有左孩子,令指针S指向P的前驱结点、指针F指向S的双亲结点,再把S指向的记录域赋给P的记录域,最后把F的右子树指向S的左子树。

 1 void DeleteBST(BTree* T, int key)
 2 {
 3     BTree P = NULL, F = NULL, S = NULL;
 4     //查找
 5     P = (* T);
 6     while (P)
 7     {
 8         if (P->data == key)
 9         {
10             break;
11         }
12         else if (P->data < key)
13         {
14             F = P;
15             P = P->Rchild;
16         }
17         else
18         {
19             F = P;
20             P = P->Lchild;
21         }
22     }
23     if (!P)//查找失败
24     {
25         return;
26     }
27 
28     if (!P->Lchild)//待删除结点没有左孩子
29     {
30         if (!F)
31         {
32             (*T) = P->Rchild;
33         }
34         else if (F->Lchild == P)
35         {
36             F->Lchild = P->Rchild;
37         }
38         else
39         {
40             F->Rchild = P->Rchild;
41         }
42         free(P);
43     }
44     else//待删除结点有左孩子,用待删除结点P的前继结点S替代P
45     {
46         F = P;
47         S = P->Lchild;
48         while (S->Rchild)
49         {
50             F = S;
51             S = S->Rchild;
52         }
53         P->data = S->data;
54         if (F != P)
55         {
56             F->Rchild = S->Lchild;
57         }
58         else
59         {
60             F->Lchild = S->Lchild;
61         }
62         free(S);
63     }
64 }

5.源代码

  1 #define _CRT_SECURE_NO_WARNINGS
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 
  5 typedef struct Node
  6 {
  7     int data;
  8     struct Node *Lchild, *Rchild;
  9 }BTNode, *BTree;
 10 
 11 int SearchBST(BTree T, BTree* P, int key)//非递归查找二叉排序树
 12 {
 13     BTree Pre = NULL;
 14     (*P) = T;
 15     while (*P)
 16     {
 17         if ((*P)->data == key)
 18         {
 19             return 1;
 20         }
 21         else if ((*P)->data < key)//右子树
 22         {
 23             Pre = (*P);
 24             (*P) = (*P)->Rchild;
 25         }
 26         else//左子树
 27         {
 28             Pre = (*P);
 29             (*P) = (*P)->Lchild;
 30         }
 31     }
 32     (*P) = Pre;
 33     return 0;
 34 }
 35 
 36 void InsertBST(BTree* T, int key)
 37 {
 38     BTree P = NULL, S = NULL;
 39     if (!SearchBST((*T), &P, key))
 40     {
 41         BTree S = (BTree)calloc(1, sizeof(BTNode));
 42         S->data = key;
 43         S->Lchild = S->Rchild = NULL;
 44         if (!P)//二叉排序树T中一个记录都没有
 45         {
 46             (*T) = S;
 47         }
 48         else if (P->data < key)
 49         {
 50             P->Rchild = S;
 51         }
 52         else
 53         {
 54             P->Lchild = S;
 55         }
 56     }
 57 }
 58 
 59 void InitBST(BTree* T)
 60 {
 61     int key = 0;
 62     FILE* fp = fopen("D:\\C\\数据结构与算法\\7.查找\\test case.txt", "r"); 
 63     while (EOF != fscanf(fp, "%d", &key))
 64     {
 65         InsertBST(&(*T), key);
 66     }
 67 }
 68 
 69 void DeleteBST(BTree* T, int key)
 70 {
 71     BTree P = NULL, F = NULL, S = NULL;
 72     //查找
 73     P = (* T);
 74     while (P)
 75     {
 76         if (P->data == key)
 77         {
 78             break;
 79         }
 80         else if (P->data < key)
 81         {
 82             F = P;
 83             P = P->Rchild;
 84         }
 85         else
 86         {
 87             F = P;
 88             P = P->Lchild;
 89         }
 90     }
 91     if (!P)//查找失败
 92     {
 93         return;
 94     }
 95 
 96     if (!P->Lchild)//待删除结点没有左孩子
 97     {
 98         if (!F)
 99         {
100             (*T) = P->Rchild;
101         }
102         else if (F->Lchild == P)
103         {
104             F->Lchild = P->Rchild;
105         }
106         else
107         {
108             F->Rchild = P->Rchild;
109         }
110         free(P);
111     }
112     else//待删除结点有左孩子,用待删除结点P的前继结点S替代P
113     {
114         F = P;
115         S = P->Lchild;
116         while (S->Rchild)
117         {
118             F = S;
119             S = S->Rchild;
120         }
121         P->data = S->data;
122         if (F != P)
123         {
124             F->Rchild = S->Lchild;
125         }
126         else
127         {
128             F->Lchild = S->Lchild;
129         }
130         free(S);
131     }
132 }
133 
134 int main(void)
135 {
136     int key = 0;
137     BTree T = NULL, P = NULL;
138     InitBST(&T);
139 
140     printf("请输入待查找的关键字:");
141     scanf("%d", &key);
142     if (SearchBST(T, &P, key))
143     {
144         printf("查找成功\n");
145     }
146     else
147     {
148         printf("查找失败\n");
149     }
150 
151     printf("请输入待删除记录的关键字:");
152     scanf("%d", &key);
153     DeleteBST(&T, key);
154 
155     printf("请输入待查找的关键字:");
156     scanf("%d", &key);
157     if (SearchBST(T, &P, key))
158     {
159         printf("查找成功");
160     }
161     else
162     {
163         printf("查找失败");
164     }
165     return 0;
166 }
二叉排序树

 

posted @ 2022-02-07 14:31  吕辉  阅读(113)  评论(0)    收藏  举报