二叉排序树的学习
经验教训:
①结构体指针声明,最前面要加struct,例如struct BSTNode *lchild;,而不是BSTNode *lchild;。
②typedef的作用:用来为复杂的声明定义简单的别名。例如,typedef struct BSTNode BST;中BST的作用等效于struct BSTNode。
③声明变量其为指针时,命名前用p,表面其是指针,会更好更直观。
④删除结点后,需要考虑到双亲结点的指向 或者 置空NULL。
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define TRUE 1 5 #define FALSE 0 6 7 typedef int elemtype; 8 9 struct BSTNode 10 { 11 elemtype data; 12 struct BSTNode *lchild; 13 struct BSTNode *rchild; 14 }; 15 16 typedef struct BSTNode BST; 17 typedef struct BSTNode * pBST; 18 19 pBST CreatBST() 20 { 21 pBST T; 22 elemtype data; 23 printf("input value of root data:"); 24 scanf("%d",&data); 25 if(!(T = (pBST)malloc(sizeof(BST)) )) 26 { 27 printf("overflow!\n"); 28 return NULL; 29 } 30 else 31 { 32 T->data = data; 33 T->lchild = NULL; 34 T->rchild = NULL; 35 } 36 return T; 37 } 38 39 pBST InsertBST(pBST q, elemtype insertData) 40 { 41 if(q == NULL) 42 { 43 if(!(q = (pBST)malloc(sizeof(struct BSTNode)) )) 44 { 45 printf("overflow!\n"); 46 return NULL; 47 } 48 q->data = insertData; 49 q->lchild = NULL; 50 q->rchild = NULL; 51 } 52 else if( insertData < q->data) 53 { 54 q->lchild = InsertBST(q->lchild, insertData); 55 } 56 else 57 { 58 q->rchild = InsertBST(q->rchild, insertData); 59 } 60 return q; 61 } 62 63 void Inorder(pBST root) 64 { 65 if(root) 66 { 67 Inorder(root->lchild); 68 printf("%d ",root->data); 69 Inorder(root->rchild); 70 } 71 } 72 73 //查找X,若成功返回结点地址,失败返回NULL 74 pBST Find(pBST root, elemtype findData) 75 { 76 while(root) { 77 if(findData < root->data) 78 root = root->lchild; 79 else if(findData > root->data) 80 root = root->rchild; 81 else 82 return root; 83 } 84 return NULL; 85 } 86 void DeletNode(pBST root, elemtype deletData) 87 { 88 pBST p = Find(root,deletData); 89 if (p->lchild) //有左孩子或者有两个孩子 90 { 91 pBST r = p->lchild; //r指向其左子树; 92 pBST prer = p->lchild; //prer指向其左子树; 93 while(r->rchild != NULL)//搜索左子树的最右边的叶子结点r 94 { 95 prer = r; 96 r = r->rchild; 97 } 98 p->data = r->data; 99 100 if(prer != r)//若r不是p的左孩子,把r的左孩子作为r的父亲的右孩子 101 prer->rchild = r->lchild; 102 else // r是p的左孩子,p的左子树最大值就是r,且r没有右子树 103 p->lchild = r->lchild; //否则结点p的左子树指向r的左子树 104 105 free(r); 106 } 107 else if(p->rchild) //只有右孩子 108 { 109 pBST r = p->rchild; //q指向其右子树; 110 pBST prer = p->rchild; //prer指向其右子树; 111 while(r->lchild != NULL) //搜索右子树的最左边的叶子结点r 112 { 113 prer = r; 114 r = r->lchild; 115 } 116 p->data = r->data; 117 118 if(prer != r)//若r不是p的右孩子,把r的右孩子作为r的父亲的左孩子 119 prer->lchild = r->rchild; 120 else // r是p的右孩子,p的右子树最小值就是r,且r没有左子树 121 p->rchild = r->rchild; //否则结点p的左子树指向r的左子树 122 123 free(r); 124 } 125 else //叶子结点 126 { 127 pBST parent; 128 while(root) 129 { 130 if(p->data > root->data) 131 { 132 parent = root; 133 root = root->rchild; 134 } 135 else if(p->data < root->data) 136 { 137 parent = root; 138 root = root->lchild; 139 } 140 else 141 break; 142 } 143 if(p->data < parent->data)//如果p是双亲的左孩子 144 parent->lchild = NULL; 145 else 146 parent->rchild = NULL; 147 free(p); 148 } 149 } 150 151 152 int main() 153 { 154 pBST tree; 155 int countNode = 0, i,deletData; 156 elemtype insertData; 157 158 pBST findNode; 159 pBST parent; 160 161 tree = CreatBST(); 162 printf("input number of node, you wanted:"); 163 scanf("%d",&countNode); 164 for(i = 0; i < countNode; i++) 165 { 166 scanf("%d",&insertData); 167 InsertBST(tree,insertData); 168 } 169 Inorder(tree); 170 printf("\n"); 171 172 printf("delete number of node, you wanted:"); 173 scanf("%d",&deletData); 174 DeletNode(tree,deletData); 175 Inorder(tree); 176 printf("\n"); 177 return 0; 178 }