本文由 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)授权。

关于作者

Deepak Kumar Gupta

架构师

印度

我热爱编程,甚至在我接受专业教育之前就开始了(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)的更多相关文章

  1. 标准模板库(STL)学习探究之vector容器

    标准模板库(STL)学习探究之vector容器  C++ Vectors vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被 ...

  2. C++的标准模板库STL中实现的数据结构之顺序表vector的分析与使用

    摘要 本文主要借助对C++的标准模板库STL中实现的数据结构的学习和使用来加深对数据结构的理解.即联系数据结构的理论分析和详细的应用实现(STL),本文是系列总结的第一篇,主要针对线性表中的顺序表(动 ...

  3. C++ 标准模板库(STL)

    C++ 标准模板库(STL)C++ STL (Standard Template Library标准模板库) 是通用类模板和算法的集合,它提供给程序员一些标准的数据结构的实现如 queues(队列), ...

  4. STL学习系列之一——标准模板库STL介绍

    库是一系列程序组件的集合,他们可以在不同的程序中重复使用.C++语言按照传统的习惯,提供了由各种各样的函数组成的库,用于完成诸如输入/输出.数学计算等功能. 1. STL介绍 标准模板库STL是当今每 ...

  5. 标准模板库--STL

    标准模板库STL 1.泛型程序设计 C++ 语言的核心优势之一就是便于软件的重用 C++中有两个方面体现重用: 1.面向对象的思想:继承和多态,标准类库 2.泛型程序设计(generic progra ...

  6. C++的标准模板库STL中实现的数据结构之链表std::list的分析与使用

    摘要 本文主要借助对C++的标准模板库STL中实现的数据结构的学习和使用来加深对数据结构的理解,即联系数据结构的理论分析和详细的应用实现(STL),本文是系列总结的第二篇.主要针对线性表中的链表 ST ...

  7. 标准模板库(STL)学习探究之stack

    标准模板库(STL)学习探究之stack queue priority_queue list map/multimap dequeue string

  8. 实验8 标准模板库STL

    一.实验目的与要求: 了解标准模板库STL中的容器.迭代器.函数对象和算法等基本概念. 掌握STL,并能应用STL解决实际问题. 二.实验过程: 完成实验8标准模板库STL中练习题,见:http:// ...

  9. C++ 标准模板库STL 队列 queue 使用方法与应用介绍

    C++ 标准模板库STL 队列 queue 使用方法与应用介绍 queue queue模板类的定义在<queue>头文件中. 与stack模板类很相似,queue模板类也需要两个模板参数, ...

  10. 【c++】标准模板库STL入门简介与常见用法

    一.STL简介 1.什么是STL STL(Standard Template Library)标准模板库,主要由容器.迭代器.算法.函数对象.内存分配器和适配器六大部分组成.STL已是标准C++的一部 ...

随机推荐

  1. Java Thread 那些事

    这篇文章被压在草稿箱许久,最近公司内部的技术社区有同学贴出了几篇分享 Java线程的文章,发觉有很多概念没有讲清楚,所以花点时间继续撰写,便有了这篇博文. 本文只聚焦 JVM 层面的线程模型,不考虑和 ...

  2. Joomla3.1.1在64位win7下安装

    将下载的joomla压缩包解压到Apache下的htdocs文件夹中. 打开Apache服务器,在浏览器输入http://localhost:8081/Joomla/ 即可进入Joolma的安装配置界 ...

  3. 解决VTune错误.../lib64/libstdc++.so.6: version `GLIBCXX_3.4.14&#39; not found (required by ...)

    错误信息及出现情景: 在export环境变量LD_PRELOAD=$XTERN_ROOT/dync_hook/interpose.so后,再执行amplxe-gui,出现上述错误.新增的动态链接库对V ...

  4. Eclipse中提高Android SDK Manager下载速度方法

    在Windows-System32-drivers-ect目录下找到hosts文件 打开hosts文件(用记事本打开就可以),在文件以下填上一下内容: 203.208.46.146 www.googl ...

  5. Flash Builder 条件编译的实现

    最近项目需要开发多个版本,  而Flash又没有像C++ 那样的 #ifdef,  来让一套代码支持多个版本的编译发布; 经过研究, 终于知道Flash Builder如何支持条件编译: 1. 在项目 ...

  6. C++建立动态二维数组

    C++建立动态二维数组主要有两种方法: 1.使用数组指针,分配一个指针数组,将其首地址保存在b中,然后再为指针数组的每个元素分配一个数组                           int * ...

  7. 【ASP.NET Web API教程】5.2 发送HTML表单数据:URL编码的表单数据

    原文:[ASP.NET Web API教程]5.2 发送HTML表单数据:URL编码的表单数据 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本系列教程,请先看前面的内 ...

  8. SQL--存储过程+触发器 对比!

    一.存储过程 一:存储过程:存储过程是一组为了完成特定功能的SQL 语句集,经编译后存储在数据库中. 可以用存储过程名字和参数来调用存储过程,这样可以避免代码重复出现,用起来也方便. 例:    下面 ...

  9. php 写session

    function do_login(){ //获取用户名和密码信息,和数据库中比对 echo 111111111; dump($_POST); dump($_SESSION); echo 222222 ...

  10. HttpClient使用详解

    http://itindex.net/detail/52566-httpclient HttpClient使用详解 标签: httpclient | 发表时间:2015-01-22 12:07 | 作 ...