用 C++ 标准模板库(STL)的 vector 实现二叉搜索树(BST)
本文由 Justme0翻译自 Code Project 转载请参见文章末尾处的要求。
介绍
众所周知,要建一棵树,我们需要关注它的内存分配与释放。为了避开这个问题,我打算用C++ STL(vector和deque)来建一棵小型的BST。很明显,这篇文章是出于这个想法的。
背景
BST是应用最广泛的数据结构之一。C是首选语言,不过因为C++尤其是C++11的出现,我更有兴趣用C++来实现。但是这篇文章里没有涉及到C++11,代码可用C++98来编译。
使用代码
要建BST,我们需要BST的数据结构。传统的BST数据结构包含指向左右子树的指针。我将用vector而不用指针,所以我将用vector的下标作为指向左右子树的指针。
struct bst
{
unsigned int data;
int leftIdx;
int rightIdx;
};
接下来,我会写各种建BST和它的孩子结点的函数。第一个函数用来建BST。它将用传入的数据来初始化数据结构,并且把左右下标置为-1(相当于置指针为NULL)。
void MakeNode(vector<struct> &v1, int aData)
{
struct bst b1 = { aData, -1, -1 };
v1.push_back(b1);
}
下面这个函数的功能是设置结点的左右孩子。设置时,会把左右孩子的真正下标(译者注:相当于它们的地址)赋到根结点上。
void setleft(vector <struct>&v1, int currIndex, int aData)
{
unsigned int leftIndex = v1.size();
v1[currIndex].leftIdx = leftIndex;
struct bst b1 = { aData, -1, -1 };
v1.push_back(b1);
} void setright(vector<struct> &v1, int currIndex, int aData)
{
unsigned int rightIndex = v1.size();
v1[currIndex].rightIdx = rightIndex;
struct bst b1 = { aData, -1, -1 };
v1.push_back(b1);
}
下面这个函数用于向BST插入数据。对所有结点(译者注:不应是“所有”,平均时间复杂度应是O(logn))遍历直至找到合适的位置插入元素,其中会调用上面定义的左右函数。
void Insert(vector<struct bst> &v1, int aData)
{
if(v1.size() == 0)
{
cout<<"Note is not made yet. MakeNode first..."<<endl;
return;
}
unsigned int currentIdx = 0;
while ( currentIdx < v1.size() )
{
if(aData <= v1[currentIdx].data)
{
if( v1[currentIdx].leftIdx == -1)
{
setleft(v1, currentIdx, aData);
break;
}
else
currentIdx = v1[currentIdx].leftIdx;
}
else
{
if(v1[currentIdx].rightIdx == -1)
{
setright(v1, currentIdx, aData);
break;
}
else
currentIdx = v1[currentIdx].rightIdx;
}
}
}
下面的代码将以前序、中序、后序遍历BST。下标参数是开始点。
void InTrav(vector <struct bst> &v1, unsigned int Idx)
{
if(v1[Idx].leftIdx != -1)
InTrav(v1,v1[Idx].leftIdx );
cout<<v1[Idx].data<<endl;
if( v1[Idx].rightIdx != -1)
InTrav(v1, v1[Idx].rightIdx);
} void PreTrav(vector <struct bst> &v1, unsigned int Idx)
{
cout<<v1[Idx].data<<endl;
if(v1[Idx].leftIdx != -1)
PreTrav(v1,v1[Idx].leftIdx );
if( v1[Idx].rightIdx != -1)
PreTrav(v1, v1[Idx].rightIdx);
}
void PostTrav(vector <struct bst> &v1, unsigned int Idx)
{
if(v1[Idx].leftIdx != -1)
PostTrav(v1,v1[Idx].leftIdx );
if( v1[Idx].rightIdx != -1)
PostTrav(v1, v1[Idx].rightIdx);
cout<<v1[Idx].data<<endl;
}
主程序比较简单,如下
int main()
{
vector <struct bst> v1;
MakeNode(v1, 30);
Insert(v1, 20);
Insert(v1, 6);
Insert(v1, 40);
Insert(v1, 35);
Insert(v1, 16);
Insert(v1, 7); InTrav(v1, 0);
PreTrav(v1,0);
PostTrav(v1,0);
return 0;
}
兴趣点
1、同样的代码也可用于STL deque。我还没为任何其他容器测试。
2、与原生指针比起来,效率较低,除非做一些vector(STL)优化。我还没去尝试。
3、你可以用它来建小型的BST,可以一下子删除它而不用担心内存释放。
4、对于BST的删除元素操作,我会在下一篇帖子中介绍。
历史
第一篇帖子
许可证
本文及相关源代码、文件,由代码项目开放许可证(CPOL)授权。
关于作者
架构师
印度
我热爱编程,甚至在我接受专业教育之前就开始了(1995年)。从那以后,我一直从事于IP网络栈(写IPv6栈和下一代TCP栈),VoIP,IP安全(IKE/IPSec)。
我最热衷的编程语言是C++,喜欢研究用加强的算法和数据结构来提高基于人工智能的系统。
原文链接:Code Project 翻译:Justme0 (@Just_me0)
译文链接:http://blog.csdn.net/justme0/article/details/11161191
[ 转载必须在正文中标注并保留原文链接、译文链接和译者等信息。]
用 C++ 标准模板库(STL)的 vector 实现二叉搜索树(BST)的更多相关文章
- 标准模板库(STL)学习探究之vector容器
标准模板库(STL)学习探究之vector容器 C++ Vectors vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被 ...
- C++的标准模板库STL中实现的数据结构之顺序表vector的分析与使用
摘要 本文主要借助对C++的标准模板库STL中实现的数据结构的学习和使用来加深对数据结构的理解.即联系数据结构的理论分析和详细的应用实现(STL),本文是系列总结的第一篇,主要针对线性表中的顺序表(动 ...
- C++ 标准模板库(STL)
C++ 标准模板库(STL)C++ STL (Standard Template Library标准模板库) 是通用类模板和算法的集合,它提供给程序员一些标准的数据结构的实现如 queues(队列), ...
- STL学习系列之一——标准模板库STL介绍
库是一系列程序组件的集合,他们可以在不同的程序中重复使用.C++语言按照传统的习惯,提供了由各种各样的函数组成的库,用于完成诸如输入/输出.数学计算等功能. 1. STL介绍 标准模板库STL是当今每 ...
- 标准模板库--STL
标准模板库STL 1.泛型程序设计 C++ 语言的核心优势之一就是便于软件的重用 C++中有两个方面体现重用: 1.面向对象的思想:继承和多态,标准类库 2.泛型程序设计(generic progra ...
- C++的标准模板库STL中实现的数据结构之链表std::list的分析与使用
摘要 本文主要借助对C++的标准模板库STL中实现的数据结构的学习和使用来加深对数据结构的理解,即联系数据结构的理论分析和详细的应用实现(STL),本文是系列总结的第二篇.主要针对线性表中的链表 ST ...
- 标准模板库(STL)学习探究之stack
标准模板库(STL)学习探究之stack queue priority_queue list map/multimap dequeue string
- 实验8 标准模板库STL
一.实验目的与要求: 了解标准模板库STL中的容器.迭代器.函数对象和算法等基本概念. 掌握STL,并能应用STL解决实际问题. 二.实验过程: 完成实验8标准模板库STL中练习题,见:http:// ...
- C++ 标准模板库STL 队列 queue 使用方法与应用介绍
C++ 标准模板库STL 队列 queue 使用方法与应用介绍 queue queue模板类的定义在<queue>头文件中. 与stack模板类很相似,queue模板类也需要两个模板参数, ...
- 【c++】标准模板库STL入门简介与常见用法
一.STL简介 1.什么是STL STL(Standard Template Library)标准模板库,主要由容器.迭代器.算法.函数对象.内存分配器和适配器六大部分组成.STL已是标准C++的一部 ...
随机推荐
- Reader开发(二)增加PDF阅读功能
最近任务很多很忙,所以更新博客的速度很慢. 大概上周就为Reader加了一个PDF阅读的功能,但是一直没时间写上来.昨晚找一下文件发现扩展了功能的Demo居然在文件目录下看不到任何文件,但是却显示有文 ...
- 在Android手机上获取其它应用的包名及版本
转载请注明出处:http://blog.csdn.net/jason_src/article/details/37757661 获取Android手机上其它应用的包名及版本方法有非常多,能够通过AAP ...
- Qt之开机自启动
Windows开机自启动的程序很多,包括系统软件.杀毒软件.一些其他安装软件等等.当然可以禁止,通过软件管理或者手动删除对应的注册表中的项即可!但是为了系统的服务或者操作上的方便,我们往往需要开机自启 ...
- Spring Configuration Check Unmapped Spring configuration files found
Spring Configuration Check Unmapped Spring configuration files found 项目中有xml文件,但没有被用IntelliJ 导入现有工程时 ...
- Mac上利用Eclipse编译Cocos2d-x
目前使用较多的Cocos2d-x开发平台是XCode,应该是由于大部分Cocos2d-x开发者都是iOS开发出生.但是当我们将XCode开发的Cocos2d-x工程发布Android版本时,每次都需要 ...
- centOS设为文本启动方式
centOS图形界面须要点用系统大量的内存和CPU资源,对于server而言,高效率是最重要的,因此将Centos 默认启动改为文本方式. 在终端中输入: vi /etc/inittab 有段说明文字 ...
- [置顶] 关于本博客 http://www.imobilebbs.com
由于时间上的关系,本博客不再和引路蜂移动软件博客同步更新, 请直接访问 http://www.imobilebbs.com 谢谢您的支持,再见 引路蜂博客
- Swift - 多线程实现方式(2) - NSOperation和NSOperationQueue
1,Swift继续使用Object-C原有的一套线程,包括三种多线程编程技术: (1)NSThread (2)Cocoa NSOperation(NSOperation和NSOperationQueu ...
- EL表达式(1)
JSP页面中支持使用EL表达式,EL全名为Expression Language.EL表达式的主要作用有: ① 获取数据: ② 执行运算: ③ 使用EL表达式的11大隐式对象: ④ 调用Java方法. ...
- Servlet的学习之Response响应对象(1)
在之前学习了Servlet中的主体结构,包括Servlet的生命周期方法,和非生命周期方法能获取的一些非常重要的对象如ServletConfig.ServletContext对象等,而从这篇开始我们将 ...