您的位置:首页 > 理论基础 > 数据结构算法

【数据结构】二分查找和二分搜索(排序)树总结

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 );
}
  • 点赞
  • 收藏
  • 分享
  • 文章举报
Professor麦发布了15 篇原创文章 · 获赞 3 · 访问量 330私信关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: