二叉排序树的C++实现(过程式)
用C的思想来写的二叉排序树。在QtCreate+win7上编译通过
头文件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #ifndef BSTree_H 2 #define BSTree_H 3 //BSTree.h 4 #define SUC 1 5 #define UNSUC 0 6 7 #include <stdlib.h> 8 #include <cstdio> 9 typedef int KeyType; 10 //还有另一种结构,带指向父节点的指针,编写方法时更简单,但存储耗费更大 11 struct BSTNode{ 12 struct BSTNode* Lchild; 13 struct BSTNode* Rchild; 14 KeyType m_KType; 15 16 }; 17 18 typedef struct BSTNode * BSTree; 19 typedef struct BSTNode * BSTNodePoint; 20 //插入,删除节点,删除树,遍历,查找 21 bool InsertNodeByValue(BSTree&, KeyType); 22 bool DeleteNodeByValue(BSTree&,KeyType); 23 bool DeleteTree(BSTree&); 24 const void TrivalAllTree(BSTree); 25 const BSTNodePoint ResearchNodeByValue(BSTree,KeyType); 26 27 #endif
源文件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //BSTree.cpp 2 #include "BSTree.h" 3 #include <iostream> 4 5 using namespace std; 6 7 bool InsertNodeByValue(BSTree &tree, KeyType value) 8 { 9 //使用的临时变量 10 BSTNodePoint p = tree , parent = NULL; 11 //创建一个新节点及初始化 12 BSTNodePoint newNode = (BSTNodePoint)malloc(sizeof(BSTNode)); 13 newNode->m_KType = value; 14 newNode->Lchild = NULL; 15 newNode->Rchild = NULL; 16 //空树则节点为其跟 17 if( NULL == tree ) 18 { 19 tree = newNode; 20 return SUC; 21 22 } 23 //新插入的结点一定是一个新添加的叶子节点, 24 //并且是查找不成功时查找路径上访问的最后一个结点的左孩子或右孩子结点。 25 while( NULL != p) 26 { 27 if( value == p->m_KType) 28 { 29 return UNSUC; 30 } 31 else 32 { 33 parent = p; 34 p = ( p->m_KType < value )? p->Rchild : p->Lchild ; 35 } 36 } 37 //parent是插入节点的父节点,以下判断插入其左或右孩子 38 if( value > parent->m_KType ) 39 { 40 parent->Rchild = newNode; 41 } 42 else 43 { 44 parent->Lchild = newNode; 45 } 46 return SUC; 47 48 49 } 50 //后序删除树,原因:由于指针会置空,后序才能不影响释放 51 bool DeleteTree(BSTree& tree) 52 { 53 54 if( NULL != tree) 55 { 56 57 DeleteTree(tree->Lchild); 58 DeleteTree(tree->Rchild); 59 cout<<"Delete key value is "<<tree->m_KType<<endl; 60 61 free(tree); 62 //置空,以防错误调用野指针 63 tree = NULL; 64 65 } 66 return SUC; 67 } 68 //中序遍历,输入有序序列 69 const void TrivalAllTree( BSTree tree) 70 { 71 if( NULL != tree ) 72 { 73 cout<<"dd"; 74 TrivalAllTree(tree->Lchild); 75 cout<<tree->m_KType<<endl; 76 TrivalAllTree(tree->Rchild); 77 } 78 79 80 } 81 const BSTNodePoint ResearchNodeByValue(BSTree tree,KeyType value) 82 { 83 if( NULL != tree) 84 { 85 if( tree->m_KType == value) 86 { 87 return tree; 88 } 89 return ResearchNodeByValue( tree->Lchild, value); 90 return ResearchNodeByValue( tree->Rchild, value); 91 92 } 93 return NULL; 94 } 95 bool DeleteNodeByValue(BSTree &tree, KeyType value) 96 { 97 98 99 BSTNodePoint parent = NULL,p = tree,q = NULL,child = NULL; 100 101 //循环结果:p指向了要删除的节点,parent被删除的节点的父节点 102 //这里也可以使用递归实现 103 while( NULL != p ) 104 { 105 if( p->m_KType == value ) 106 { 107 break; 108 } 109 else 110 { 111 parent = p; 112 p = ( p->m_KType < value ) ? p->Rchild : p->Lchild ; 113 } 114 115 116 } 117 if( NULL == p) 118 {return UNSUC;} 119 120 //q用于后面判断 121 q = p; 122 //rchild & lchild exist*/ 123 //转换成单个孩子的情况*/ 124 if( NULL != p->Lchild && NULL != p->Rchild) 125 { 126 parent = p; 127 p = p->Rchild; 128 //p指向要删除节点的右子树的最左节点,parent是p的父节点,使删除操作巧妙的转移 129 while( NULL != p->Lchild) 130 { 131 parent = p; 132 p = p->Lchild ; 133 } 134 child = p->Rchild; 135 136 137 } 138 else if( NULL != p->Lchild ) 139 { 140 child = p->Lchild; 141 } 142 else if( NULL != p->Rchild ) 143 { 144 child = p->Rchild; 145 } 146 else 147 { 148 child = NULL; 149 } 150 151 //parent被删除的节点的父节点 152 //p被删除的节点 153 //child被删除节点的孩子 154 // 155 156 //parent指向child*/ 157 if( NULL == parent) 158 { 159 tree = child; 160 } 161 else 162 { 163 if( p == parent->Lchild ) 164 { 165 parent->Lchild = child; 166 } 167 else 168 { 169 parent->Rchild = child; 170 } 171 //发生了转换操作后,实质等同于交换节点 172 if( q != p ) 173 { 174 q->m_KType = p->m_KType; 175 } 176 } 177 178 //删除 179 free(p); 180 p = NULL; 181 return SUC; 182 183 184 }
测试函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //BSTree-test-main 2 3 4 5 #include <iostream> 6 #include "BSTree.h" 7 using namespace std; 8 9 int main() 10 { 11 cout << "Hello World!" << endl; 12 13 BSTree tree = NULL; 14 bool staus = InsertNodeByValue(tree, 3); 15 InsertNodeByValue(tree, 2); 16 //cout<<tree->m_KType<<endl; 17 InsertNodeByValue(tree, 15); 18 InsertNodeByValue(tree, 8); 19 InsertNodeByValue(tree, 17); 20 //TrivalAllTree(tree); 21 TrivalAllTree(tree); 22 bool staus2 = DeleteNodeByValue(tree,15); 23 cout<<"staus2 : "<<staus2<<endl; 24 TrivalAllTree(tree); 25 DeleteTree(tree); 26 TrivalAllTree(tree); 27 return 0; 28 }