二叉排序树
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 }

浙公网安备 33010602011771号