标签:
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均不小于它的根结点的值; 它的左、右子树也分别为二叉排序树。
二叉排序树的查找过程和二叉树类似,通常采取二叉链表作为二叉排序树的存储结构。中序遍历二叉排序树可得到一个关键字的有序序列,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程即为对无序序列进行排序的过程。每次插入的新的结点都是二叉排序树上新的叶子结点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。搜索、插入、删除的复杂度等于树高O(log(n)).
特性:1.从根节点一直往左走,知道无左路可走,即得到最小元素;从根节点一直往右左,直到无右路可走,即得到最大元素。
2.一个节点的后继节点,必定无左子树,有或者没有右子树;一个节点的前驱节点,必定无右子树,有或者没有左子树。
二叉查找树的插入过程如下:1.若当前的二叉查找树为空,则插入的元素为根节点,2.若插入的元素值小于根节点值,则将元素插入到左子树中,3.若插入的元素值不小于根节点值,则将元素插入到右子树中。
#ifndef SEARCHBITREE_H #define SEARCHBITREE_H #include <iostream> //定义二叉树结点结构 typedef struct BiNode{ int data; struct BiNode *lchild; struct BiNode *rchild; BiNode(int value):data(value),lchild(NULL),rchild(NULL){} }*BiTree; //二叉查找树查找算法,如果不存在则返回false,存在则返回ture bool SearchValue(BiTree root,int value){ while(root!=NULL){ if(root->data==value) return true; else if(root->data>value) root=root->lchild; else root=root->rchild; } return false; } //二叉查找树插入算法(建立二叉树算法) void InsertSearchTree(BiTree &root,int value){ //如果为空树,则插入 if(root==NULL){ root=new BiNode(value); }else{ //根节点值大于插入值,则插入左子树 if(root->data>value) InsertSearchTree(root->lchild,value); else //插入右子树 InsertSearchTree(root->rchild,value); } } //中序遍历二叉查找树,得到的是一个有序序列 void InorderTraverse(BiTree root){ if(root!=NULL){ InorderTraverse(root->lchild); std::cout<<root->data<<" "; InorderTraverse(root->rchild); } } //获得二叉查找树最大值,如果为空树,则返回-1 int FindMax(BiTree root){ if(root==NULL) return -1; while(root->rchild!=NULL){ root=root->rchild; } return root->data; } //获得二叉查找树最小值,如果为空树,则返回-1 int FindMin(BiTree root){ if(root==NULL) return -1; while(root->lchild!=NULL){ root=root->lchild; } return root->data; } //得到待删除结点的父节点和本身结点指针 void findPostion(BiTree root, int deleteValue, BiTree& deleteNode,BiTree& parentNode){ deleteNode=root; while(deleteNode!=NULL){ if(deleteNode->data==deleteValue){ return; }else if(deleteNode->data>deleteValue){ parentNode=deleteNode; deleteNode=deleteNode->lchild; }else{ parentNode=deleteNode; deleteNode=deleteNode->rchild; } } } //二叉查找树删除算法 void DeleteSearchTree(BiTree &root,int deleteValue){ BiTree deleteNode=NULL,parentNode=NULL; //得到待删除结点的指针和指向父节点的指针 findPostion(root,deleteValue,deleteNode,parentNode); //std::cout<<parentNode->data<<" "<<deleteNode->data<<std::endl; //待删除结点是叶子结点(特殊情况只有一个根节点,需要特殊处理) if(deleteNode->lchild==NULL && deleteNode->rchild==NULL){ if(deleteNode=parentNode->lchild) parentNode->lchild=NULL; else if(deleteNode=parentNode->rchild) parentNode->rchild=NULL; else //删除的是根节点 parentNode=NULL; delete deleteNode; }else if(deleteNode->lchild==NULL && deleteNode->rchild!=NULL){ //待删除结点只有右子树 if(root->data==deleteNode->data)//删除的是根节点 root=deleteNode->rchild; else{ if(deleteNode==parentNode->lchild) parentNode->lchild=deleteNode->rchild; else parentNode->rchild=deleteNode->rchild; } delete deleteNode; }else if(deleteNode->lchild!=NULL && deleteNode->rchild==NULL){ //待删除结点只有左子树 if(root->data==deleteNode->data)//删除的是根节点 root=deleteNode->rchild; else{ if(deleteNode==parentNode->lchild) parentNode->lchild=deleteNode->lchild; else parentNode->rchild=deleteNode->lchild; } delete deleteNode; }else{ //待删除结点既有左子树又有右子树 BiTree temp = deleteNode->lchild; BiTree tempParent = deleteNode; //找到待删除结点的直接前驱 while(temp->rchild != NULL){ tempParent = temp; temp = temp->rchild; } //交换待删除结点和其前驱结点的值 deleteNode->data = temp->data; //此处有两种情况需要考虑,具体自己画图分析 if(tempParent->lchild == temp){ tempParent->lchild = temp->lchild; }else{ tempParent->rchild = temp->lchild; } delete temp; } } #endif
#include<iostream> #include "searchBiTree.h" using namespace std; int main(){ BiTree root=NULL; int value[]={15,5,16,3,12,20,10,13,18,23,6,7}; //插入建立二叉查找树 for(int i=0;i<12;i++){ InsertSearchTree(root,value[i]); } //中序遍历二叉查找树,得到有序序列 cout<<"中序遍历二叉查找树: "; InorderTraverse(root); cout<<endl; //获得二叉查找树最大值 cout<<"二叉查找树最大值: "<<FindMax(root)<<endl; //获得二叉查找树最小值 cout<<"二叉查找树最大值: "<<FindMin(root)<<endl; //二叉查找树查找算法 cout<<"查找11: "<<boolalpha<<SearchValue(root,11)<<endl; cout<<"查找12: "<<SearchValue(root,12)<<endl; //二叉查找树删除算法 cout<<"删除结点12后输出: "; DeleteSearchTree(root,12); InorderTraverse(root); return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/sxhlovehmm/article/details/47356605