【数据结构】二分查找和二分搜索(排序)树总结
2020-01-11 17:40
369 查看
二分查找法
注意边界的关系
// 二分查找法,在有序数组arr中,查找target // 如果找到target,返回相应的索引index // 如果没有找到target,返回-1 template<typename T> int binarySearch(T arr[], int n, T target){// 在arr[l...r]之中查找target int l = 0, r = n-1; while( l <= r ){ //直到l大于r的时候这个边界才会消失//int mid = (l + r)/2; 这个可能会出现越界问题 int mid = l + (r-l)/2; //用最小的值加一个范围再除以2 if( arr[mid] == target ) return mid;if( arr[mid] > target ) r = mid - 1; else l = mid + 1; }return -1; }// 用递归的方式写二分查找法 template<typename T> int __binarySearch2(T arr[], int l, int r, T target){if( l > r ) return -1;int mid = (l+r)/2; if( arr[mid] == target ) return mid; else if( arr[mid] > target ) return __binarySearch2(arr, 0, mid-1, target); else return __binarySearch2(arr, mid+1, r, target);}
二分搜索树:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w8DqDb4p-1578325196082)(C:\Users\professor\Desktop\捕获.PNG)]
从上表可以看出二分搜索树是很高效的,无论是查找还是插入还是删除,所以在维护程序的时候,用二分排序树是很有必要的!二分搜索树不一定是一棵完全二叉树,所以它不能用数组来,要用指针和结点来表示
template <typename Key, typename Value> class BST{private: struct Node{ Key key; Value value; Node *left; Node *right;Node(Key key, Value value){ this->key = key; this->value = value; this->left = this->right = NULL; } };Node *root; int count; public: BST(){ root = NULL; count = 0; } ~BST(){ // TODO: ~BST() }int size(){ return count; }bool isEmpty(){ return count == 0; } };
//用递归的方式插入一个结点 // 向以node为根的二叉搜索树中,插入节点(key, value) // 返回插入新节点后的二叉搜索树的根 Node* insert(Node *node, Key key, Value value){if( node == NULL ){ count ++; return new Node(key, value); }if( key == node->key ) node->value = value; else if( key < node->key ) node->left = insert( node->left , key, value); else // key > node->key node->right = insert( node->right, key, value);return node; }
// 查看以node为根的二叉搜索树中是否包含键值为key的节点 bool contain(Node* node, Key key){if( node == NULL ) return false;if( key == node->key ) return true; else if( key < node->key ) return contain( node->left , key ); else // key > node->key return contain( node->right , key ); }
// 在以node为根的二叉搜索树中查找key所对应的value Value* search(Node* node, Key key){ //用Value*是为了防止查找失败的时候返回一个空而使程序崩溃,而用指针则可以保存空值if( node == NULL ) return NULL;if( key == node->key ) return &(node->value); else if( key < node->key ) return search( node->left , key ); else // key > node->key return search( node->right, key ); }
//递归的方法对树进行遍历 // 对以node为根的二叉搜索树进行前序遍历 void preOrder(Node* node){if( node != NULL ){ cout<<node->key<<endl; preOrder(node->left); preOrder(node->right); } }// 对以node为根的二叉搜索树进行中序遍历 void inOrder(Node* node){if( node != NULL ){ inOrder(node->left); cout<<node->key<<endl; inOrder(node->right); } }// 对以node为根的二叉搜索树进行后序遍历 void postOrder(Node* node){if( node != NULL ){ postOrder(node->left); postOrder(node->right); cout<<node->key<<endl; } }
层序遍历就是广度优先遍历(要用队列)
// 层序遍历 void levelOrder(){queue<Node*> q; q.push(root); //入队根结点 while( !q.empty() ){Node *node = q.front(); //取出队首元素 q.pop(); //出队cout<<node->key<<endl; //一层 if( node->left ) q.push( node->left ); //左孩子入队 if( node->right ) q.push( node->right ); //右孩子入队 } }
删除
// 在以node为根的二叉搜索树中,返回最小键值的节点 Node* minimum(Node* node){ if( node->left == NULL ) return node;return minimum(node->left); }// 在以node为根的二叉搜索树中,返回最大键值的节点 Node* maximum(Node* node){ if( node->right == NULL ) return node;return maximum(node->right); }// 删除掉以node为根的二分搜索树中的最小节点 // 返回删除节点后新的二分搜索树的根 Node* removeMin(Node* node){if( node->left == NULL ){Node* rightNode = node->right; delete node; count --; return rightNode; }node->left = removeMin(node->left); return node; }// 删除掉以node为根的二分搜索树中的最大节点 // 返回删除节点后新的二分搜索树的根 Node* removeMax(Node* node){if( node->right == NULL ){Node* leftNode = node->left; delete node; count --; return leftNode; }node->right = removeMax(node->right); return node; }
// 寻找最小的键值 Key minimum(){ assert( count != 0 ); Node* minNode = minimum( root ); return minNode->key; }// 寻找最大的键值 Key maximum(){ assert( count != 0 ); Node* maxNode = maximum(root); return maxNode->key; }// 从二叉树中删除最小值所在节点 void removeMin(){ if( root ) root = removeMin( root ); }// 从二叉树中删除最大值所在节点 void removeMax(){ if( root ) root = removeMax( root ); }
ximum(root);
return maxNode->key;
}
// 从二叉树中删除最小值所在节点 void removeMin(){ if( root ) root = removeMin( root ); }// 从二叉树中删除最大值所在节点 void removeMax(){ if( root ) root = removeMax( root ); }
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- C语言 数据结构之排序与查找 数据结构实验之查找四:二分查找
- 数据结构---排序与二分查找
- SDUT_3376_数据结构实验之查找四:二分查找
- 59.排序好的大数据创建索引文件,并实现大文件的二分查找,根据索引百万数据秒读数据
- 数据结构与算法-----搜索和排序(C语言库函数的使用)
- 数据结构实验之查找四:二分查找
- 数据结构实验之查找四:二分查找
- 【数据结构】二分查找及它的演变——插值查找
- 数据结构与算法总结——排序(三)桶排序,计数排序和基数排序
- C语言 数据结构排序与查找 数据结构实验之排序五:归并求逆序数
- 数据结构实践——二叉树排序树中查找的路径
- C++数据结构与STL--二分查找
- 数据结构实验8-二分查找与二叉排序树
- 数据结构之排序和查找
- java数据结构之排序总结
- 数据结构及简单算法的总结----之【排序】
- 数据结构之排序总结1
- 数据结构 二分查找 输出前k大的数
- 数据结构实验之查找四:二分查找
- 排序和搜索(二)——python实现二分查找