C++超详细快速掌握二叉搜索树_第1页
C++超详细快速掌握二叉搜索树_第2页
C++超详细快速掌握二叉搜索树_第3页
C++超详细快速掌握二叉搜索树_第4页
C++超详细快速掌握二叉搜索树_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第C++超详细快速掌握二叉搜索树目录二叉搜索树概念与操作二叉搜索树的概念二叉搜索树的操作查找插入删除二叉搜索树的应用二叉树的性能分析

二叉搜索树概念与操作

二叉搜索树的概念

二叉搜索树又称二叉排序树,若它的左子树不为空,则左子树上所有节点的值都小于根节点的值;若它的右子树不为空,则右子树上所有节点的值都大于根节点的值,它的左右子树也分别未二叉搜索树。也可以是一颗空树。

inta[]={5,3,4,1,7,8,2,6,0,9};

二叉搜索树的操作

查找

迭代:

Node*Find(constKkey)

Node*cur=_root;

while(cur)

if(cur-_keykey)

cur=cur-_right;

elseif(cur-_keykey)

cur=cur-_left;

else

returncur;

returnnullptr;

}

递归:

Node*_FindR(Node*root,constKkey)

if(root==nullptr)

returnnullptr;

if(root-_keykey)

return_FindR(root-_right,key);

elseif(root-_keykey)

return_FindR(root-_left,key);

else

returnroot;

}

插入

树为空,则直接插入

树不为空,按二叉搜索树性质查找插入位置,插入新节点

迭代:

boolInsert(constKkey)

if(_root==nullptr)

_root=newNode(key);

returntrue;

//查找要插入的位置

Node*parent=nullptr;

Node*cur=_root;

while(cur)

if(cur-_keykey)

parent=cur;

cur=cur-_right;

elseif(cur-_keykey)

parent=cur;

cur=cur-_left;

else

returnfalse;

cur=newNode(key);

if(parent-_keycur-_key)

parent-_right=cur;

else

parent-_left=cur;

returntrue;

}

递归:

bool_InsertR(Node*root,constKkey)

if(root==nullptr)

root=newNode(key);

returntrue;

else

if(root-_keykey)

return_InsertR(root-_left,key);

elseif(root-_keykey)

return_InsertR(root-_left,key);

else

returnfalse;

}

删除

首先查找元素是否在二叉搜索树中,如果不存在,则返回,否则要删除的结点可能分下面四种情况:

要删除的结点无孩子结点

要删除的结点只有左孩子结点

要删除的结点只有右孩子结点

要删除的结点只有左、右结点

实际情况中1和2或3可以合并,因此真正的删除过程如下:

删除该结点且使被删除结点的双亲结点指向被删除结点的左孩子结点

删除该结点且使被删除结点的双亲结点指向被删除结点的右孩子结点

替代法。在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除结点中,再来处理该结点的删除问题。

迭代:

boolErase(constKkey)

Node*parent=nullptr;

Node*cur=_root;

while(cur)

if(cur-_keykey)

parent=cur;

cur=cur-_right;

elseif(cur-_keykey)

parent=cur;

cur=cur-_left;

else

//删除

if(cur-_left==nullptr)

if(cur==_root)

_root=cur-_right;

else

if(cur==parent-_left)

parent-_left=cur-_right;

else

parent-_right=cur-_right;

deletecur;

elseif(cur-_right==nullptr)

if(cur==_root)

_root=cur-_left;

else

if(cur==parent-_left)

parent-_left=cur-_left;

else

parent-_right=cur-_left;

else

//找到右树最小节点去替代删除

Node*minRightParent=cur;

Node*minRight=cur-_right;

while(minRight-_left)

minRightParent=minRight;

minRight=minRight-_left;

cur-_key=minRight-_key;

if(minRight==minRightParent-_left)

minRightParent-_left=minRight-_right;

else

minRightParent-_right=minRight-_right;

deleteminRight;

returntrue;

returnfalse;

}

递归:

bool_EraseR(Node*root,constKkey)

if(root==nullptr)

returnfalse;

if(root-_keykey)

return_EraseR(root-_right,key);

elseif(root-_keykey)

return_EraseR(root-_left,key);

else

//删除

Node*del=root;

if(root-_left==nullptr)

root=root-_right;

elseif(root-_right==nullptr)

root=root-_left;

else

//替代法删除

Node*minRight=root-_right;

while(minRight-_left)

minRight=minRight-_left;

root-_key=minRight-_key;

//转换成递归在右子树中删除最小节点

return_EraseR(root-_right,minRight-_key);

deletedel;

returntrue;

}

二叉搜索树的应用

1.K模型:K模型即只有key作为关键码,结构中只需要存储key即可,关键码即为需要搜索到的值。比如:给一个单词word,判断该单词是否拼写正确。具体方法如下:1.以单词集合中的每个单词作为key,构建一棵二叉搜索树。2.在二叉搜索树中检索该单词是否存在,存在则拼写正确,不存在则拼写错误。

2.KV模型:每一个关键码key,都有与之对应的值Value,即Key,Value的键值对。该种方式在现实生活中非常常见:比如英汉词典就是英语与中文的对应关系,通过英文可以快速找到与其对应的中文,英文单词与其对应的中文word,chinese就构成一种键值对;再比如统计单词次数,统计成功后,给定单词就可快速找到其出现的次数,单词与其出现次数就是word,count就构成一种键值对。

比如:实现一个简单的英汉词典dict,可以通过英文找到与其对应的中文,具体实现方式如下:1.单词,中文含义为键值对构造二叉搜索树,注意:二叉搜索树需要比较,键值对比较时只比较Key。2.查询英文单词时,只需要给出英文单词,就可快速找到与其对应的Key。

namespaceKEY_VALUE{

templateclassK,classV

structBSTreeNode

BSTreeNodeK,V*_left;

BSTreeNodeK,V*_right;

K_key;

V_value;

BSTreeNode(constKkey,constVvalue)

:_left(nullptr)

,_right(nullptr)

,_key(key)

,_value(value)

templateclassK,classV

classBSTree{

typedefBSTreeNodeK,VNode;

public:

Voperator[](constKkey)

pairNode*,boolret=Insert(key,V());

returnret.first-_value;

pairNode*,boolInsert(constKkey,constVvalue)

if(_root==nullptr)

_root=newNode(key,value);

returnmake_pair(_root,true);

//查找要插入的位置

Node*parent=nullptr;

Node*cur=_root;

while(cur)

if(cur-_keykey)

parent=cur;

cur=cur-_right;

elseif(cur-_keykey)

parent=cur;

cur=cur-_left;

else

returnmake_pair(cur,false);

cur=newNode(key,value);

if(parent-_keycur-_key)

parent-_right=cur;

else

parent-_left=cur;

returnmake_pair(cur,true);

Node*Find(constKkey)

Node*cur=_root;

while(cur)

if(cur-_keykey)

cur=cur-_right;

elseif(cur-_keykey)

cur=cur-_left;

else

returncur;

returnnullptr;

boolErase(constKkey)

Node*cur=_root;

Node*parent=nullptr;

while(cur)

if(cur-_keykey)

parent=cur;

cur=cur-_right;

elseif(cur-_keykey)

parent=cur;

cur=cur-_left;

else

//删除

if(cur-_left==nullptr)

if(cur==_root)

_root=cur-_right;

else

if(cur==parent-_left)

parent-_left=cur-_left;

else

parent-_right=cur-_right;

deletecur;

elseif(cur-_right==nullptr)

if(cur==_root)

_root=cur-_left;

else

if(cur==parent-_left)

parent-_left=cur-_left;

else

parent-_right=cur-_right;

deletecur;

else

//找到右树

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论