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 }