二叉排序树

  1 BinarySortTreeADT.h
2 /*
3 *二叉排序树(Binary Sort Tree)又称二叉查找(搜索)树(Binary Search Tree)。
4 *其定义为:二叉排序树或者是空树,或者是满足如下性质的二叉树:
5 *①若它的左子树非空,则左子树上所有结点的值均小于根结点的值;
6 *②若它的右子树非空,则右子树上所有结点的值均大于根结点的值;
7 *③左、右子树本身又各是一棵二叉排序树。
8 *上述性质简称二叉排序树性质(BST性质),故二叉排序树实际上是满足BST性质的二叉树。
9 */
10 #ifndef _BINARYSORTTREEADT_H
11 #define _BINARYSORTTREEADT_H
12
13 /* 声明结点的值的类型 */
14 typedef int KeyType;
15
16 /* 声明结点类型 */
17 typedef struct CBSTNode
18 {
19 KeyType m_ktKey;
20 struct CBSTNode * m_pCBSTNLeft;
21 struct CBSTNode * m_pCBSTNRight;
22 }CBSTNode, *PCBSTNode, *CBSTree;
23
24 /* 向二叉排序树中加入一个结点 */
25 extern int InsertNode(CBSTree *, KeyType);
26
27 /* 通过值查找并删除一个结点 */
28 extern int DelNode(CBSTree *, KeyType);
29
30 /* 通过值查找结点并返回结点的指针(设为常量指针) */
31 extern const CBSTNode * SearchNode(CBSTree *, KeyType);
32
33 /* 中序遍历二叉排序树的结点 */
34 extern void PrintAllNodeMid(CBSTree);
35
36 /* 后序方式释放结点 */
37 extern void FreeBSTree(CBSTree);
38 #endif
39
40 BinarySortTreeADT.cpp
41 #include "BinarySortTreeADT.h"
42 #include <stdlib.h>
43 #include <stdio.h>
44
45 /* 向二叉排序树中加入一个结点 */
46 int InsertNode(CBSTree * tree, KeyType key)
47 {
48 PCBSTNode p = NULL, parent = NULL;
49 PCBSTNode pNewNode = (PCBSTNode)malloc(sizeof(CBSTNode));
50 if (NULL == pNewNode)
51 {
52 return -1;
53 }
54 /* 新建结点赋值,特别是左右子结点指针要赋值为NULL */
55 pNewNode->m_ktKey = key;
56 pNewNode->m_pCBSTNLeft = NULL;
57 pNewNode->m_pCBSTNRight = NULL;
58 /* 二叉排序树是空树 */
59 if (NULL == *tree)
60 {
61 *tree = pNewNode;
62 return 0;
63 }
64 else
65 {
66 p = *tree;
67 /* 寻找插入位置 */
68 while (NULL != p)
69 {
70 /* key值已在二叉排序树中 */
71 if (p->m_ktKey == key)
72 {
73 return 0;
74 }
75 else
76 {
77 parent = p;
78 p = (p->m_ktKey < key) ? p->m_pCBSTNRight : p->m_pCBSTNLeft;
79 }
80 }
81 if (parent->m_ktKey < key)
82 {
83 parent->m_pCBSTNRight = pNewNode;
84 }
85 else
86 {
87 parent->m_pCBSTNLeft = pNewNode;
88 }
89 return 0;
90 }
91 }
92
93 /* 通过值查找并删除一个结点 */
94 int DelNode(CBSTree * tree, KeyType key)
95 {
96 PCBSTNode p = NULL, q = NULL, parent = NULL, child = NULL;
97 p = *tree;
98 /* parent为NULL表示根结点的父亲为NULL */
99 while (NULL != p)
100 {
101 if (p->m_ktKey == key)
102 {
103 break;
104 }
105 else
106 { parent = p;
107 p = (p->m_ktKey < key) ? p->m_pCBSTNRight : p->m_pCBSTNLeft;
108 }
109 }
110 /* p为NULL时, 表示没有找到结点值为key的结点 */
111 if (NULL == p)
112 {
113 return 0;
114 }
115 /* p, q现在都是保存了待删结点指针 */
116 q = p;
117
118 /* 待删结点有两个儿子结点,进行一下转化 */
119 if (NULL != p->m_pCBSTNLeft && NULL != p->m_pCBSTNRight)
120 {
121 parent = p;
122 p = p->m_pCBSTNRight;
123 while (NULL != p->m_pCBSTNLeft)
124 {
125 parent = p;
126 p = p->m_pCBSTNLeft;
127 }
128 /* p中保存了待删结点右子树中最左下的结点指针, parent中就保存了该结点父亲指针 */
129 child = p->m_pCBSTNRight;
130 }
131
132 /* parent保存待删结点的父亲结点指针, child保存了待删结点的儿子结点
133 指针(待删结点至多只有一个儿子, 有两个会转化为0个或1个右结点)*/
134
135 /* 待删结点是根结点 */
136 if (NULL == parent)
137 {
138 *tree = child;
139 }
140 else
141 {
142 /*待删结点是父亲结点的左儿子*/
143 if (parent->m_pCBSTNLeft == p)
144 {
145 parent->m_pCBSTNLeft = child;
146 }
147 else
148 {
149 parent->m_pCBSTNRight = child;
150 }
151 /*待删结点有两个儿子结点, 转化后需要交换两个结点值 */
152 if (p != q)
153 {
154 q->m_ktKey = p->m_ktKey;
155 }
156 }
157 free(p);
158 return 0;
159 }
160
161 /* 通过值查找结点并返回结点的指针(设为常量指针) */
162 const CBSTNode * SearchNode(CBSTree * tree, KeyType key)
163 {
164 PCBSTNode p = *tree;
165 while (NULL != p)
166 {
167 if (p->m_ktKey == key)
168 {
169 break;
170 }
171 else
172 {
173 p = (p->m_ktKey < key) ? p->m_pCBSTNRight : p->m_pCBSTNLeft;
174 }
175 }
176 return p;
177 }
178
179 /* 中序遍历二叉排序树的结点 */
180 void PrintAllNodeMid(CBSTree tree)
181 {
182 if (NULL != tree)
183 {
184 PrintAllNodeMid(tree->m_pCBSTNLeft);
185 printf("%d is accessed./n", tree->m_ktKey);
186 PrintAllNodeMid(tree->m_pCBSTNRight);
187 }
188 }
189
190 /* 后序方式释放结点 */
191 void FreeBSTree(CBSTree tree)
192 {
193 if (NULL != tree)
194 {
195 FreeBSTree(tree->m_pCBSTNLeft);
196 FreeBSTree(tree->m_pCBSTNRight);
197 printf("%d is free./n", tree->m_ktKey);
198 free(tree);
199 }
200 }


编辑器加载中...

posted on 2012-02-25 15:34  万里心晴  阅读(1812)  评论(0编辑  收藏  举报