(1)、逼近二分查找的查找算法;
(2)、一般不允许出现重复数字,不然没法存储;
(3)、满足:左孩子数据 < 根结点数据 < 右孩子数据;根(父)结点比左孩子的大,比右孩子的小;
(4)、左子树和右子树也是二叉搜索树。
2、为什么叫二叉搜索树
如果对一颗二叉搜索树进行中序遍历,可以按从小到大的顺序输出,此时又叫做二叉排序树。
如图:
3、小堆
堆的构造,i>数组直接生成堆(向下调整),ii>插入创建堆(向上调整);
(1)、怎么实现一次调整?
找到最后一个非叶子结点,n/2-1;一直往下调整即可!
(2)、堆排----->优先级队列
堆的删除,只能是堆顶元素,再拿最后一个元素补充上去。在向下做一次调整。形成新的堆结构(满足堆的性质),将删除的数字输出就是堆排。
小堆:根(父)小于左右结点;最小的数字先出;
大堆:根(父)大于左右结点;最大的数字先出;因而,进行堆排序就是优先级队列!
4、线索二叉树的查找父结点图形解释
利用空指针指向前驱、后继结点。
5、编程时 const 一些注意
(1)、在C++中,当我们传的是常量时,引用接收时,形参必须const类型接受,否则出错!
常量必须常引用接受。
1int find(32); 23int find(const int &value);
(2)、typedef void *IP
const IP m;怎么理解?
因为IP是数据类型,const和数据类型可以互换位置;const IP m; <==> IP const m; 即 void *const m; m 是一个指针,其指向不能更改,其指向的空间数据可以更改!
6、搜索二叉树上的操作
全部用 C++ 实现的。
(1)、之前学习二叉树,并没有说什么插入,删除操作,那是因为,没有规律而言,怎么进行操作呢?搜索二叉树的规律如此明显,那么插入,删除必是重中之重!
(2)、我们输入相同的数字,但是顺序不同的话,生成的搜索二叉树是不一样的!
例:int ar[] = {3, 7, 9, 1, 0, 6, 4, 2,}; 和int ar[] = {7, 3, 9, 1, 0, 6, 4, 2,}; 生成的搜索二叉树不一样。
(3)、插入函数
利用搜索二叉树的性质:
1void insert(BSTreeNode *&t, const Type &x){
2 if(t == NULL){
3 t = new BSTreeNode(x); 4 return; 5 }else if(x data){ 6 insert(t->leftChild, x); 7 }else if(x > t->data){ 8 insert(t->rightChild, x); 9 }else{10 return;11 } 12}
(4)、删除函数
思想:要删除一个有左孩子或右孩子或是叶子结点,看成一种情况,做法:保存要删除的结点,因为传的是引用,可以直接修改上一个结点的左孩子或右孩子,使其跨过当前的直指下一个结点,在释放当前的结点空间。
第二种情况:就是要删除的既有左子树,又有右子树,此时可以有两种做法:i>找左子树最大的数字,覆盖要删除的数字,在往左子树找这个数字删除-->递归!ii>找右子树最小的数字,覆盖要删除的数字,在往右子树找这个数字删除-->递归!
第一种情况图形想法如下:
删除左边和删除右边,还有是叶子结点,想法一样。
第二种情况图形想法如下:
代码如下:
1bool remove(BSTreeNode *&t, const Type &key){
2 if(t == NULL){ //t传的是引用,每次可以进行直接更改!
3 return false;
4 }
5
6 if(key data){
7 remove(t->leftChild, key);
8 }else if(key > t->data){
9 remove(t->rightChild, key);
10 }else{
11 if(t->leftChild != NULL && t->rightChild != NULL){ //第二种情况
12 BSTreeNode *p = t->rightChild;13 while(p->leftChild != NULL){14 p = p->leftChild;15 }16 t->data = p->data;17 remove(t->rightChild, p->data); //在右树找p->data的数字进行删除;18 }else{ //第一种情况19 BSTreeNode *p = t;20 if(t->leftChild == NULL){21 t = t->rightChild; //引用的好处体现出来了;22 }else{ 23 t = t->leftChild; //引用的好处体现出来了;24 }25 delete p;26 }27 } 28 return true;29}30/* 以下这个代码是先想到的,比较容易,上面这个是经过思考的,将三种情况看成一种情况来处理。31bool remove(BSTreeNode *&t, const Type &key){32 if(t == NULL){33 return false;34 }3536 if(key data){37 remove(t->leftChild, key);38 }else if(key > t->data){39 remove(t->rightChild, key);40 }else{ //以下三种情况可以看成一种;41 if(t->leftChild == NULL && t->rightChild == NULL){42 delete t;43 t = NULL;44 }else if(t->leftChild != NULL && t->rightChild == NULL){45 BSTreeNode *p = t;46 t = t->leftChild;47 delete p;48 }else if(t->leftChild == NULL && t->rightChild != NULL){49 BSTreeNode *p = t;50 t = t->rightChild;51 delete p;52 }else{53 BSTreeNode *p = t->rightChild;54 while(p->leftChild != NULL){55 p = p->leftChild;56 }57 t->data = p->data;58 remove(t->rightChild, p->data);59 }60 } 61 return true;62}63*/
7、搜索二叉树的完整代码、测试代码、测试结果
(1)、完整代码
1#ifndef _BSTREE_H_
2#define _BSTREE_H_
3
4#include
5using namespace std;
6
7#define MIN_NUMBER -8937589
8#define MAX_NUMBER 99999999
9
10
11template<typename Type>
12class BSTree;
13
14template<typename Type>
15class BSTreeNode{
16 friend class BSTree;
17public:
18 BSTreeNode() : data(Type()), leftChild(NULL), rightChild(NULL){}
19 BSTreeNode(Type d, BSTreeNode *left = NULL, BSTreeNode *right = NULL)
20 : data(d), leftChild(left), rightChild(right){}
21 ~BSTreeNode(){}
22private:
23 Type data;
24 BSTreeNode *leftChild;
25 BSTreeNode *rightChild;
26};
27
28template<typename Type>
29class BSTree{
30public:
31 BSTree() : root(NULL){}
32 BSTree& operator=(const BSTree &bst){ 33 if(this != &bst){ 34 root = copy(bst.root); 35 } 36 37 return *this; 38 } 39 ~BSTree(){} 40public: 41 void insert(const Type &x){ 42 insert(root, x); 43 } 44 void inOrder()const{ 45 inOrder(root); 46 } 47 Type Min()const{ 48 return Min(root); 49 } 50 Type Max()const{ 51 return Max(root); 52 } 53 BSTreeNode* find(const Type &key)const{ 54 return find(root, key); 55 } 56 BSTreeNode *copy(const BSTreeNode *t){ 57 if(t == NULL){ 58 return NULL; 59 } 60 BSTreeNode *tmp = new BSTreeNode(t->data); 61 tmp->leftChild = copy(t->leftChild); 62 tmp->rightChild = copy(t->rightChild); 63 64 return tmp; 65 } 66 BSTreeNode* parent(const Type &key)const{ 67 return parent(root, key); 68 } 69 bool remove(const Type &key){ 70 return remove(root, key); 71 } 72protected: 73 bool remove(BSTreeNode *&t, const Type &key){ 74 if(t == NULL){ //重点:传的是引用 75 return false; 76 } 77 78 if(key data){ 79 remove(t->leftChild, key); 80 }else if(key > t->data){ 81 remove(t->rightChild, key); 82 }else{ 83 if(t->leftChild != NULL && t->rightChild != NULL){ 84 BSTreeNode *p = t->rightChild; 85 while(p->leftChild != NULL){ 86 p = p->leftChild; 87 } 88 t->data = p->data; 89 remove(t->rightChild, p->data); 90 }else{ 91 BSTreeNode *p = t; 92 if(t->leftChild == NULL){ 93 t = t->rightChild; //可以直接更改左右孩子 94 }else{ 95 t = t->leftChild; //可以直接更改左右孩子 96 } 97 delete p; 98 99 }100 }101102 return true;103 }104/* 105 bool remove(BSTreeNode *&t, const Type &key){106 if(t == NULL){107 return false;108 }109110 if(key data){111 remove(t->leftChild, key);112 }else if(key > t->data){113 remove(t->rightChild, key);114 }else{ //以下三种情况可以看成一种;115 if(t->leftChild == NULL && t->rightChild == NULL){116 delete t;117 t = NULL;118 }else if(t->leftChild != NULL && t->rightChild == NULL){119 BSTreeNode *p = t;120 t = t->leftChild;121 delete p;122 }else if(t->leftChild == NULL && t->rightChild != NULL){123 BSTreeNode *p = t;124 t = t->rightChild;125 delete p;126 }else{127 BSTreeNode *p = t->rightChild;128 while(p->leftChild != NULL){129 p = p->leftChild;130 }131 t->data = p->data;132 remove(t->rightChild, p->data);133 }134 }135136 return true;137 }*/138 BSTreeNode* parent(BSTreeNode *t, const Type &key)const{139 if(t == NULL || t->data == key){140 return NULL;141 }142 if(t->leftChild->data == key || t->rightChild->data == key){143 return t;144 }145 if(key data){146 return parent(t->leftChild, key);147 }else{148 return parent(t->rightChild, key);149 }150 }151 BSTreeNode* find(BSTreeNode *t, const Type &key)const{152 if(t == NULL){153 return NULL;154 }155156 if(t->data == key){157 return t;158 }else if(key data){159 return find(t->leftChild, key);160 }else{161 return find(t->rightChild, key);162 }163 }164 Type Max(BSTreeNode *t)const{165 if(t != NULL){166 while(t->rightChild){167 t = t->rightChild;168 }169170 return t->data;171 }172173 return MAX_NUMBER;174 }175 Type Min(BSTreeNode *t)const{176 if(t != NULL){177 while(t->leftChild){178 t = t->leftChild;179 }180181 return t->data;182 }183 return MIN_NUMBER;184 }185 void inOrder(BSTreeNode *t)const{186 if(t != NULL){187 inOrder(t->leftChild);188 cout<data<<" ";189 inOrder(t->rightChild);190 }191 }192 void insert(BSTreeNode *&t, const Type &x){193 if(t == NULL){194 t = new BSTreeNode(x);195 return;196 }else if(x data){197 insert(t->leftChild, x);198 }else if(x > t->data){199 insert(t->rightChild, x);200 }else{201 return;202 } 203 }204private:205 BSTreeNode *root;206};207#endif
(2)、测试代码
1#include"bstree.h"
2
3int main(void){
4 int ar[] = {3, 7, 9, 1, 0, 6, 4, 2,};
5 int n = sizeof(ar) / sizeof(int);
6 BSTree<int> bst;
7 for(int i = 0; i 8 bst.insert(ar[i]);
9 }
10
11 bst.inOrder();
12 cout<<endl;
13 cout<endl;14 cout<endl;15 BSTreeNode<int> *p = bst.find(6);16 BSTreeNode<int> *q = bst.parent(4);17 printf("%p %p\n", p, q);18 bst.remove(0);19 bst.inOrder();20 cout<<endl;21 return 0;22}
(3)、测试结果
推荐阅读:
从零开始学习数据结构-->入门篇 从零开始学习数据结构-->链表 从零开始学习数据结构-->线性表 从零开始学习数据结构-->栈 从零开始学习数据结构-->队列 从零开始学习数据结构-->矩阵+串 从零开始学习数据结构-->哈希表 从零开始学习数据结构-->散列桶 从零开始学习数据结构-->二叉树从零开始学习数据结构-->二叉树方法实现
从零开始学习数据结构-->线索二叉树从零开始学习数据结构-->树、森林与二叉树的转换
从零开始学习数据结构-->大堆+小堆
认真的人 自带光芒