数据结构(复习)--------关于二叉查找树
1. 查找树的创建(createTree)
假设有如下数组4,1,45,78,345,23,12,3,6,21
首先选定4为root,然后遍历剩下的数字,如果大于等于4则放到4的右侧,小于4放到4的左侧,最后构建成的树:所有的左孩子都小于父节点,所有的右孩子都大于等于父节点。如下图:
2. 遍历查找树(displayTree)
按照左中右的顺序遍历树,结果为:1,3,4,5,12,21,23,45,78,345,遍历的结果就是已经排好序的数字。
3. 查找树中的节点(searchTree)
从根节点开始,如果大于等于根节点,则查找根节点的右侧;如果小于根节点,则查找根节点的左侧,直到查找到节点。
比如要查找12:
比4大,往右走;
比45小,往左走;
比23小,往左走;
找到12
4. 删除树中的节点(deleteNode)
这个是最复杂的,因为删除完节点后要重新构建树,涉及到的情况很多:
a.要删除的node没有左右孩子,有父节点。
如果要删除的node为父节点的左孩子,则将父节点的左孩子指针设置为NULL;如果要删除的node为父节点的右孩子,则将父节点的右孩子指针设置为NULL。最后删除node。
b.要删除的node没有左右孩子,没有父节点(即根节点)。
根节点设为NULL,删除node。
c.要删除的node有左孩子没右孩子,有父节点
如果要删除的node为父节点的左孩子,则将父节点的左孩子设置为要被删除node的左孩子;如果要删除的node为父节点的右孩子,则将父节点的右孩子指针设置为要被删除node的左孩子。最后删除node。
d.要被删除的node有左孩子没有右孩子,没有父节点
将要被删除的node的左孩子设置为根节点,删除node。
e.要删除的node有右孩子没左孩子,有父节点
如果要删除的node为父节点的左孩子,则将父节点的左孩子设置为要被删除node的右孩子;如果要删除的node为父节点的右孩子,则将父节点的右孩子指针设置为要被删除node的右孩子。最后删除node。
f.要被删除的node有右孩子没有左孩子,没有父节点
将要被删除的node的右孩子设置为根节点,删除node。
g.要被删除的node左右孩子都有,有父节点
将要被删除node的右孩子插入到左孩子中去。如果要删除的node为父节点的左孩子,则将父节点的左孩子设置为要被删除node的左孩子;如果要删除的node为父节点的右孩子,则将父节点的右孩子指针设置为要被删除node的左孩子。最后删除node。
h.要被删除的node左右孩子都有,无父节点
将要被删除node的右孩子插入到左孩子中去,父节点修改为要被删除node的左孩子,删除node
-------------------------------------------------------------------------------------------------------------------------------------------------------------
//关于二叉查找树的算法 #include <cstdio> #include <cstdlib> //#define _OJ_ typedef struct tree { int data; struct tree *lchild; struct tree *rchild; } tree, *Bitree; Bitree Find_x(Bitree T, int x) { if(T == NULL) { printf("没有找到!\n"); return NULL;} if(T->data < x) Find_x(T->rchild, x); else if(T->data > x) Find_x(T->lchild, x); else return T; }//递归查找元素没找到则返回null包括根节点返回null代表没有找到 Bitree Find_min(Bitree T) { if(T->lchild == NULL) return T; else T->lchild = Find_min(T->lchild); } //找最大的元素和最小元素递归与非递归的写法 Bitree Find_max(Bitree T) { while (T->rchild != NULL) {T = T->rchild; printf("%d\n", T->data);} return T; } Bitree Insert_elem(Bitree T, int x) { if(T == NULL) { T = (Bitree) malloc (sizeof(tree)); T->lchild = T->rchild = NULL; T->data = x; } else if(x < T->data) T->lchild = Insert_elem(T->lchild, x); else if(x > T->data) T->rchild = Insert_elem(T->rchild, x); return T; } Bitree detele_elem(Bitree T, int x) { Bitree tmp; if(T->data > x) T->lchild = detele_elem(T->lchild, x); else if(T->data < x) T->rchild = detele_elem(T->rchild, x); else if(T->lchild != NULL && T->rchild != NULL) { tmp = Find_min(T->rchild); T->data = tmp->data; detele_elem(T->rchild, T->data); //有两个儿子那么把右子树最小元素替代此节点 再删除最小的那个元素 } else { tmp = T; if(T->lchild == NULL) T = T->rchild; else if(T->lchild == NULL) T = T->lchild; }//有一个或者零个元素 return T; } Bitree build_tree(Bitree T, int n) { int i, x; for (i = 0; i < n; i++) { scanf("%d", &x); printf("%d\n", x); T = Insert_elem(T, x); } return T; } int main(int argc, char const *argv[]) { #ifndef _OJ_ //ONLINE JUDGE freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); #endif Bitree T = NULL, T1 = NULL; int n; scanf("%d", &n); T = build_tree(T, n); printf("T == %p\n", T); T1 = Find_x(T, 3); printf("%d\n", T1->data); T1 = Find_min(T); printf("min == %d\n", T1->data); T1 = Find_max(T); printf("max == %d\n", T1->data); detele_elem(T, 5); T1 = Find_max(T); printf("max1 == %d\n", T1->data); return 0; }