排序二叉树实现map容器.docx
- 文档编号:18207828
- 上传时间:2023-04-24
- 格式:DOCX
- 页数:14
- 大小:16.61KB
排序二叉树实现map容器.docx
《排序二叉树实现map容器.docx》由会员分享,可在线阅读,更多相关《排序二叉树实现map容器.docx(14页珍藏版)》请在冰豆网上搜索。
排序二叉树实现map容器
用排序二叉树实现map容器(原)C++2009-12-2223:
56:
32阅读169评论0字号:
大中小订阅
这几天心血来潮,用排序二叉树实现了一个简单的map
晚上把上周排序二叉树的删除给实现了,排序树的删除本来想着挺简单,结果晚上搞了3个钟头才搞定。
做的过程中对排序二叉树体会有几点:
排序二叉树总结:
1.查找
查找是其他操作的前提,因为插入和删除的时候都用到了查找
查找的时候树可以抽象成一个三角形,运用递归的方法很容易就能实现
2.插入
做的过程中发现一句话很精髓:
排序二叉树插入的节点肯定是叶节点。
明白上面的道理了实现起来就很容易了。
3.删除
实现的方法是,先整理右子树,把右子树中最小的元素作为右子树的根节点,然后用这个根节点代替删除的节点。
按照这种思路,那么左子树中最大的元素替换应该也能实现同样的功能,没有编码实现,只实现了上面那种方法。
删除是操作里面最麻烦的了,想着就头疼,因为要保持树的性质。
测试过程中如果顺序插入元素那么生成的树就是一个线性表,使用效率肯定不高,下步实现个平衡树。
代码贴出来:
#ifndef__BST_H__
#define__BST_H__
template
classSpiderMap
{
private:
structNode
{
Kkey;
Tvalue;
//父节点
Node*pP;
//左孩子
Node*pL;
//右孩子
Node*pR;
Node():
key(-1),
pP(NULL),
pL(NULL),
pR(NULL)
{
}
};
public:
typedefNode*iterator;
public:
SpiderMap();
~SpiderMap();
//查找接口
constiteratorfind(Kk);
//插入接口
voidinsert(Kk,Tt);
//删除接口
voiddelNode(Kk);
private:
//具体的查找实现
Node*_find(Node*mRoot,Kkey);
//将要删除节点的右子树进行整理
Node*_trim(Node*mRoot);
private:
Node*mRoot;
};
template
SpiderMap
:
SpiderMap():
mRoot(0)
{
}
template
SpiderMap
:
~SpiderMap()
{
}
/**
*查找接口
*找到了返回当前节点指针
*找不到返回空迭代器
*/
template
consttypenameSpiderMap
:
iteratorSpiderMap
:
find(Kk)
{
Node*node=newNode();
node->key=k;
iteratoriter=_find(mRoot,node->key);
if(iter->key==k)
{
returniter;
}
deletenode;
returnNULL;
}
/**
*插入接口
*把传入的键值对插入到当前的树中
*/
template
voidSpiderMap
:
insert(Kk,Tt)
{
//创造一个节点
iteratornode=newNode();
node->key=k;
node->value=t;
//首先判断当前的树是否为空树
if(mRoot==NULL)
{
mRoot=node;
}
else
{
//如果不是空树就查找应该插入的父节点位置
iteratoriter=_find(mRoot,node->key);
if(iter->key!
=node->key)
{
//判断应该插到左子树还是右子树
(iter->key>node->key)?
(iter->pL=node):
(iter->pR=node);
//给节点的父节点赋值
node->pP=iter;
}
}
}
/**
*删除节点
*总体思路,删除的节点是以下类型:
*1)叶子
*2)只有左子树
*3)只有右子树
*4)有左右子树
*/
template
voidSpiderMap
:
delNode(Kkey)
{
//将要删除的元素
iteratorcurrent;
current=_find(mRoot,key);
if(current->key!
=key)
{
//树中没有指定删除的元素
return;
}
//删除的元素是叶子节点
if(NULL==current->pL&&NULL==current->pR)
{
//如果是根节点
if(current==mRoot)
{
deletemRoot;
mRoot=NULL;
}
//如果是左孩子
elseif(current->pP->pL!
=NULL)
{
if(current->pP->pL->key==current->key)
{
iteratortemp=current->pP->pL;
current->pP->pL=NULL;
deletetemp;
}
}
//如果是右孩子
if(current->pP->pR!
=NULL)
{
if(current->pP->pR->key==current->key)
{
iteratortemp=current->pP->pR;
current->pP->pR=NULL;
deletetemp;
}
}
}
//删除的元素只有左子树
elseif(NULL!
=current->pL&&NULL==current->pR)
{
//如果是根节点
if(current==mRoot)
{
iteratortemp=mRoot;
mRoot=current->pL;
mRoot->pP=NULL;
deletetemp;
}
//如果是左孩子
elseif(current->pP->pL!
=NULL)
{
if(current->pP->pL->key==current->key)
{
iteratortemp=current;
current->pP->pL=current->pL;
current->pL->pP=current->pP;
deletetemp;
}
}
//如果是右孩子
if(current->pP->pR!
=NULL)
{
if(current->pP->pR->key==current->key)
{
iteratortemp=current;
current->pP->pR=current->pL;
current->pL->pP=current->pP;
deletetemp;
}
}
}
//删除的元素只有右子树
elseif(NULL==current->pL&&NULL!
=current->pR)
{
//如果是根节点
if(current==mRoot)
{
iteratortemp=current;
mRoot=current->pR;
current->pP=NULL;
deletetemp;
}
//如果是左孩子
elseif(current->pP->pL!
=NULL)
{
if(current->pP->pL->key==current->key)
{
iteratortemp=current;
current->pP->pL=current->pR;
current->pR->pP=current->pP;
deletetemp;
}
}
//如果是右孩子
if(current->pP->pR!
=NULL)
{
if(current->pP->pR->key==current->key)
{
iteratortemp=current;
current->pP->pR=current->pR;
current->pR->pP=current->pP;
deletetemp;
}
}
}
//删除的元素有左右子树
elseif(NULL!
=current->pL&&NULL!
=current->pR)
{
iteratorrightTree=_trim(current);
//如果是根节点
if(current==mRoot)
{
iteratortemp=current;
rightTree->pL=current->pL;
current->pL->pP=rightTree;
mRoot=rightTree;
mRoot->pP=NULL;
deletetemp;
}
//如果是左孩子
elseif(current->pP->pL!
=NULL)
{
if(current->pP->pL->key==current->key)
{
iteratortemp=current;
rightTree->pL=current->pL;
current->pP=rightTree;
mRoot->pL=rightTree;
rightTree->pP=mRoot;
deletetemp;
}
}
//如果是右孩子
if(current->pP->pR!
=NULL)
{
if(current->pP->pR->key==current->key)
{
iteratortemp=current;
rightTree->pL=current->pL;
current->pL=rightTree;
mRoot->pR=rightTree;
rightTree->pP=mRoot;
deletetemp;
}
}
}
}
/**
*内部的查找
*找到了返回当前指针
*找不到返回应插入的父节点指针
*/
template
typenameSpiderMap
:
iteratorSpiderMap
:
_find(typenameSpiderMap
:
Node*mRoot,Kkey)
{
//这里应该写个比较函数比较合适
if(mRoot->key>key)
{
//小于当前值并且没有左子树返回父节点
if(mRoot->pL==NULL)
{
returnmRoot;
}
//小于当前值并且有左子树就递归查找左子树
return(_find(mRoot->pL,key));
}
elseif(mRoot->key { //大于当前值并且没有右子树就返回父节点 if(mRoot->pR==NULL) { returnmRoot; } //大于当前值别且有右子树就递归查找右子树 return(_find(mRoot->pR,key)); } elseif(mRoot->key==key) { returnmRoot; } } /** *将要删除节点的右子树进行整理 */ template typenameSpiderMap : Node*SpiderMap : _trim(typenameSpiderMap : Node*root) { iteratorparent=root; iteratorcurrent=root->pR; //找到传入节点的右子树中最小的节点 while(NULL! =current->pL) { parent=current; current=current->pL; } //如果开始的current就是最小的就不做处理 if(root->pR! =current) { parent->pL=current->pR; current->pR->pP=parent; current->pR=parent; } returncurrent; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 排序 二叉 实现 map 容器