二叉查找树
1 复习时,手画一棵查找树,亲自摸清查找树的各操作 2 二叉查找树的定义 3 一颗空树或该非空树满足: 4 1,若有左子树,左子树的所有节点小于根节点 5 2,若有右子树,右子树的所有节点大于根节点*/ 6 /*二叉查找树的一些性质 7 1.查找某个关键字的比较次数最多是树的深度, 8 模拟过程是从树根往下沿着 9 某一路径走到叶子结点。查找性能取决于树的形态 10 2.同一组数,会因插入的顺序不同,生成不同形态的查找树。 11 ①按照有序序列插入,生成单支树,最坏情况时间复杂度是n/2 12 ②最好情况和折半查找判定树相同,时间复杂度是log2(n) 13 ③随机输入情况下,时间复杂度是log(n) 14 3.中序遍历二叉树是个有序序列 15 4,删除一个结点,操作较复杂: 16 ①待删结点p是叶子结点,待删结点的父节点的相应孩子指针域修改成空 17 ②待删结点p只有一棵子树,待删结点的父节点的相应孩子指针域 18 修改成p->child 19 ③待删结点有两棵子树,分两种情况: 20 p的左孩子有右孩子,最右的孩子的数据代替p的数据,删除最右孩子 21 p的左孩子没有右孩子,p的左孩子的数据代替p的数据,删除p的左孩子 22 总而言之,就是把以p为树根的树的最大结点的值代替p的值,删除之 23 最大结点其实是中序遍历时,p的直接前驱。 24 ④删除结点是根结点时,要分开讨论,因为根结点没有父节点且会改变*T 25 */ 26 /*详细笔记,关于查找2函数*/ 27 typedef struct node { 28 int data; 29 struct node *lchild, *rchild; 30 }BSTNode, *BST; 31 /*在二叉查找树中插入新结点*/ 32 /*1,如果树空,即第一次插入结点,树根是新结点 33 2,树不空,新结点等于根,不必插入,返回错误信息 34 新结点小于根,插入左子树;大于根,插入右子树*/ 35 Status BSTInsert(BST *T, int elem) { 36 if (NULL == *T){ 37 *T = (BST)malloc(sizeof(BSTNode)); 38 (*T)->data = elem; 39 (*T)->lchild = NULL; 40 (*T)->rchild = NULL; 41 } 42 /*以下三个if条件语句是互斥执行的*/ 43 if (elem == (*T)->data) 44 return error; 45 else if (elem < (*T)->data) 46 return BSTInsert(&(*T)->lchild, elem); 47 else/*递归必须有return,否则编译器VS13会给出警告, 48 请仔细思考递归*/ 49 return BSTInsert(&(*T)->rchild, elem); 50 } 51 /*调用插入函数,通过数组构建含有n个元素的查找树 */ 52 void InputData(BST *T, int *a, int n) { 53 *T = NULL; 54 for (int i = 0; i < n; ++i) 55 BSTInsert(T, a[i]); 56 } 57 /*利用递归查找关键字key,查找成功返回指针,失败返回空指针*/ 58 BSTNode* SearchBST(BST T, int key) { 59 if (NULL == T) 60 return NULL;//递归结束条件(还可作为形参是空树的处理操作) 61 else { 62 if (key == T->data) 63 return T;//根是目标元素,返回 64 else if (key < T->data) {//小于根,找左子树 65 return SearchBST(T->lchild, key); 66 //【注意】必须要有return,否则编译器会给出警告 67 } 68 else {//大于根,找右子数 69 return SearchBST(T->rchild, key); 70 }/*注意:左子树和右子树只找了一个。普通二叉树的查找,左右子树 71 都找了,注意二者判断条件的区别*/ 72 } 73 } 74 /*非递归在二叉排序树查找关键字key,查找成功返回指针,失败返回空指针*/ 75 BSTNode* SearchBST2(BST T, int key) { 76 BSTNode *p = T; 77 while (NULL != p && key != p->data) { 78 if (key < p->data) 79 p = p->lchild; 80 else 81 p = p->rchild; 82 } 83 return p; 84 } 85 /*删除一个结点,并接上她的左右子树*/ 86 Status DeleteNode(BST *T, int key) { 87 BST p, q, maxchild, secmaxchild; 88 if (NULL == *T) 89 return error; 90 p = *T; 91 q = NULL; 92 while (NULL != p && key != p->data) { 93 q = p; 94 if (key < p->data) 95 p = p->lchild; 96 else 97 p = p->rchild; 98 } 99 if (p == *T) { 100 printf("删除的是树根,需改变*T,未编,结束函数\n"); 101 return error; 102 } 103 if (NULL == p) 104 return error; 105 else { 106 /*待删结点p是叶子结点,q是其父节点*/ 107 if (NULL == p->lchild && NULL == p->rchild) { 108 if (p == q->lchild) 109 q->lchild = NULL; 110 if (p == q->rchild) 111 q->rchild = NULL; 112 free(p); p = NULL; 113 } 114 /*待删结点p只有一棵子树,q直接将其删除*/ 115 else if (NULL != p->lchild && NULL == p->rchild) { 116 if (p == q->lchild) 117 q->lchild = p->lchild; 118 if (p == q->rchild) 119 q->rchild = p->lchild; 120 free(p); p = NULL; 121 } 122 else if (NULL == p->lchild && NULL != p->rchild) { 123 if (p == q->lchild) 124 q->lchild = p->rchild; 125 if (p == q->rchild) 126 q->rchild = p->rchild; 127 free(p); p = NULL; 128 } 129 /*待删结点p有两棵子树*/ 130 else if (NULL != p->lchild && NULL != p->rchild) { 131 secmaxchild = p; 132 maxchild = p->lchild; 133 while (NULL != maxchild->rchild) { 134 secmaxchild = maxchild; 135 maxchild = maxchild->rchild; 136 } 137 if (maxchild != p->lchild) { 138 p->data = maxchild->data; 139 if (maxchild->lchild != NULL) { 140 secmaxchild->rchild = maxchild->lchild; 141 } 142 } 143 else { 144 p->data = maxchild->data; 145 p->lchild = maxchild->lchild; 146 } 147 free(maxchild); maxchild = NULL; 148 } 149 return ok; 150 } 151 }