数据结构 二叉查找树 BST

来源:互联网 发布:网页编程html 编辑:程序博客网 时间:2024/05/18 09:04

二叉查找树:又称为 二叉排序树   二叉搜索树

首先,这几个名字都让我觉得混乱,简单地讲,二叉树的重要的应用便是查找了,因此“查找”与“搜索”二字等价,可以理解。那么又由于二叉搜索树的中序遍历是有序的,因此又叫做二叉排序树。

接下来,步入正题:[摘自维基百科]

二叉查找树Binary Search Tree),也称有序二叉树(ordered binary tree),排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树:

  1. 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  2. 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  3. 任意节点的左、右子树也分别为二叉查找树。
  4. 没有键值相等的节点(no duplicate nodes)。
如下图就是一个二叉查找树。



首先定义二叉查找树的操作:由于二叉树的递归定义,下述的方法只需要递归编写即可。

1    insert插入操作(在树root中添加节点值为target的节点)

注意:传入参数为root的引用,也可将新形成的树作为返回值。

//insert nodevoid insert(TreeNode * &root, int target){TreeNode *node = new TreeNode(target);if( root == NULL ) {root = node;return;}if ( target == root->val ){cout << target << " exists ..." << endl;}else if (target < root->val){insert(root->left, target);}else{insert(root->right , target);}}

2    创建二叉搜索树,根据一个已知数组的元素集合创建一个二叉搜索树。

PS:依次插入数组中的每个元素即可,如果数组有序,那么二叉搜索树将退化为一个链表。

TreeNode * convertArrayToBST(int data[], int len){if(len == 0) return NULL;TreeNode *root = NULL;for(int i = 0 ; i < len ; ++i ){insert(root, data[i]);}return root;}

3   查找元素  并返回true/false,并设置findPtr用于标记该节点是否找到。

//findPtr 必须传引用,否则会出错(传值 VS 传址)bool search(TreeNode *root, int target , TreeNode * & findPtr){if(root == NULL){return false;}cout << "search..." << root->val << endl; TreeNode *temp = root;if(target == temp->val){findPtr = temp;cout << "find " << findPtr->val << endl;return true;}else if (target > temp->val){return search(temp->right , target, findPtr );}else{return search(temp->left , target ,findPtr );}}

4   返回最大值或者最小值


//find min elementTreeNode *findMin(TreeNode *root){if( root == NULL) return NULL;if ( root->left == NULL ) return root;elsereturn findMin( root->left );}//find max elementTreeNode *findMax(TreeNode *root){if( root == NULL ) return NULL;if( root->right == NULL) return root;else return findMax(root->right);}

5   将二叉搜索树转换为一个双向有序链表 (最常见的问题)

TreeNode *convert(TreeNode *root){if(root == NULL) return NULL;stack<TreeNode *> s;TreeNode *temp = root;TreeNode *head = NULL;TreeNode *pre = NULL;while(temp || !s.empty()){while(temp){s.push(temp);temp = temp->left;}temp = s.top();s.pop();if(head == NULL){head = temp;head->left = NULL;pre = head;temp = temp->right;continue;}if(pre){pre->right = temp;temp->left = pre;pre = temp;temp = temp->right;}}return head;}

完整的代码为:
#include<iostream>#include<stack>using namespace std;struct TreeNode{int val;TreeNode *left,*right;TreeNode(int x):val(x),left(NULL),right(NULL){}};TreeNode *convert(TreeNode *root){if(root == NULL) return NULL;stack<TreeNode *> s;TreeNode *temp = root;TreeNode *head = NULL;TreeNode *pre = NULL;while(temp || !s.empty()){while(temp){s.push(temp);temp = temp->left;}temp = s.top();s.pop();if(head == NULL){head = temp;head->left = NULL;pre = head;temp = temp->right;continue;}if(pre){pre->right = temp;temp->left = pre;pre = temp;temp = temp->right;}}return head;}//insert nodevoid insert(TreeNode * &root, int target){TreeNode *node = new TreeNode(target);if( root == NULL ) {root = node;return;}if ( target == root->val ){cout << target << " exists ..." << endl;}else if (target < root->val){insert(root->left, target);}else{insert(root->right , target);}}//find min elementTreeNode *findMin(TreeNode *root){if( root == NULL) return NULL;if ( root->left == NULL ) return root;elsereturn findMin( root->left );}//find max elementTreeNode *findMax(TreeNode *root){if( root == NULL ) return NULL;if( root->right == NULL) return root;else return findMax(root->right);}TreeNode * convertArrayToBST(int data[], int len){if(len == 0) return NULL;TreeNode *root = NULL;for(int i = 0 ; i < len ; ++i ){insert(root, data[i]);}return root;}//findPtr 必须传引用,否则会出错(传值 VS 传址)bool search(TreeNode *root, int target , TreeNode * & findPtr){if(root == NULL){return false;}cout << "search..." << root->val << endl; TreeNode *temp = root;if(target == temp->val){findPtr = temp;cout << "find " << findPtr->val << endl;return true;}else if (target > temp->val){return search(temp->right , target, findPtr );}else{return search(temp->left , target ,findPtr );}}void InOrderTraverse2(TreeNode *root){if( root == NULL ) return;InOrderTraverse2(root->left);cout << root->val << " ";InOrderTraverse2(root->right);}void PreOrderTraverse2(TreeNode *root){if( root == NULL ) return;cout << root->val << " ";PreOrderTraverse2(root->left);PreOrderTraverse2(root->right);}void InOrderTraverse(TreeNode *root){cout << "InOrderTraverse..." << endl;if( root == NULL ) return;TreeNode *pre = NULL;while(root){if(root->left == NULL){cout << root->val << " ";root = root->right;continue;}//if left not nullfor(pre = root->left; pre->right && pre->right != root ; pre = pre->right);//the first visiting time//for循环退出的条件是pre->rigth == NULL或者是pre->right == root.//分别考虑for循环退出的情况。if(pre->right == NULL){pre->right = root;root = root->left;}//the second visiting time//说明当前节点的左子树已经访问过了else{cout << root->val << " ";root = root->right;pre->right = NULL;}}}int main(){TreeNode *node6 = new TreeNode(6);TreeNode *node2 = new TreeNode(2);TreeNode *node8 = new TreeNode(8);TreeNode *node1 = new TreeNode(1);TreeNode *node4 = new TreeNode(4);TreeNode *node3 = new TreeNode(3);node6->left = node2;node6->right = node8;node2->left = node1;node2->right = node4;node4->left = node3;TreeNode *findPtr = NULL;InOrderTraverse(node6);cout << endl;InOrderTraverse2(node6);cout << endl;PreOrderTraverse2(node6);cout << endl;cout << "find min " << findMin(node6)->val << endl;cout << "find max " << findMax(node6)->val << endl;//add node 7if ( search(node6,2,findPtr))cout << findPtr->val << endl;else{insert(node6,2);cout << "not find.." << endl;}InOrderTraverse(node6);cout << "InOrderTraverse iterativelly..." << endl;InOrderTraverse2(node6);cout << endl;PreOrderTraverse2(node6);cout << endl;cout << "find min " << findMin(node6)->val << endl;cout << "find max " << findMax(node6)->val << endl;//convert to sorted listTreeNode *head = convert(node6);cout << "head = " << head->val << endl;head = head->right;while(head && head->right){cout << head->left->val << " " << head->val  << " " << head->right->val << endl;head = head->right;}cout << endl;//build BSTint data[] = {1,4,3,2};int len = sizeof(data)/sizeof(int);cout << "build BST..." << endl;TreeNode *root = convertArrayToBST(data, len);InOrderTraverse(root);cout << "InOrderTraverse iterativelly..." << endl;InOrderTraverse2(root);cout << "PreOrderTraverse..." << endl;PreOrderTraverse2(root);cout << endl;return 0;}




3 0
原创粉丝点击