二叉排序树 C++

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据结构课程设计

第9题

yuhao

2016-1-3

目录

1系统分析 (2)

1.1项目需求分析 (2)

1.2系统功能分析 (2)

1.2.1功能函数(Function) (2)

1.2.2采用的数据结构介绍 (2)

1.3系统需求分析 (3)

2系统设计及其实现分析 (3)

2.1系统总体设计 (3)

2.2系统运行流程图 (4)

2.3功能实现分析 (4)

3系统测试 (6)

4 Bug Report (7)

5总结与分析 (7)

1系统分析

1.1项目需求分析

依次输入关键字并建立二叉排序树,实现二叉排序数的查找、插入和删除功能。

二叉排序树就是指将原来已有的数据根据大小构成一棵二叉树,二叉树中的所有结点数据满足一定的大小关系,所有的左子树中的结点均比根结点小,所有的右子树的结点均比根结点大。

二叉排序树查找是指按照二叉排序树中结点的关系进行查找,查找关键自首先同根结点进行比较,如果相等则查找成功;如果比根节点小,则在左子树中查找;如果比根结点大,则在右子树中进行查找。这种查找方法可以快速缩小查找范围,大大减少查找关键的比较次数,从而提高查找的效率。

二叉排序树插入,先找到待插入位置,再进行插入。注意在插入过程中要比较与树中结点的数值,数值相同的不能插入。

1.2系统功能分析

1.2.1功能函数(Function)

void Init(); //类初始化函数

void buildTree(); //建树

Node *getRoot(); //获取根结点

Node *Find(int data); //查找结点函数

bool Insert(int data); //向树中插入元素函数

Node *searchSuccessor(Node *node); //寻找某个结点的后继

Node *searchMin(Node *node); //查找最小值

bool Delete(Node *node); //从树中删除函数

void Release(Node *node); //释放结点空间

void Show(Node *node); //打印树结点值函数

1.2.2采用的数据结构介绍

二叉排序树又称“二叉查找树”、“二叉搜索树”。

二叉排序树:或者是一棵空树,或者是具有下列性质的二叉树:

1.若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;

2.若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

3.它的左、右子树也分别为二叉排序树。

如图即为一棵二叉排序树。

二叉排序树通常采用二叉链表作为存储结构。中序遍历二叉排序树可得到一个依据关键字的有序序列,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程即是对无序序列进行排序的过程。每次插入的新的结点都是二叉排序树上新的叶子结点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。搜索、插入、删除的时间复杂度等于树高,期望O(logn),最坏O(n)(数列有序,树退化成线性表,如右斜树)。

1.3系统需求分析

(1)硬件环境:

此项目极为简单,硬件环境无须赘述。

(2)软件环境:

操作系统:win7及以上

调试环境:visual studio 2010及以上

2系统设计及其实现分析

2.1系统总体设计

基于需求,首先创建一个二叉排序树中结点的结构体,定义其值,左子结点,右子结点,父结点的指针。

接着声明二叉排序树类,类中声明各种功能函数。

最后在主函数中将类实例化并调用功能函数实现项目需求。

2.2系统运行流程图

2.3功能实现分析

void Init(); //类初始化函数

将root置为NULL。

void buildTree(); //建树

将用户输入的所有元素一一加入到树中,相当于执行数次insert()函数。

Node *getRoot(); //获取根结点

返回Node类型的root结点。

Node *Find(int data); //查找结点函数

自root开始查找,若data小于当前结点值,则寻找结点的左子树,否则右子树,直至找到此结点。若至树底还未找到,则输出警示信息。

bool Insert(int data); //向树中插入元素函数

首先寻找到待插位置,自顶向下,若data小于结点值,则搜寻左子树;否则搜寻右子树,至树底时,若其值大于父结点值则放在右子树;否则放在左子树。

Node *searchSuccessor(Node *node); //寻找某个结点的后继

采用中序遍历,若此结点有右子树,则其后继为右子树中值最小的结点;若无,则遍历其左子树,直到找到一个结点位于父结点的左子树,则这个父结点就是我们要找到的结点的后继。

Node *searchMin(Node *node); //查找最小值

一直往左孩子找,知道结点无左孩子,则它就是最小值的结点。

bool Delete(Node *node); //从树中删除函数

在二叉排序树删去一个结点,分三种情况讨论:

若*p结点为叶子结点,即PL(左子树)和PR(右子树)均为空树。由于删去叶子结点不破坏整棵树的结构,则可以直接删除此子结点。

若*p结点只有左子树PL或右子树PR,此时只要令PL或PR直接成为其双亲结点*f 的左子树(当*p是左子树)或右子树(当*p是右子树)即可,作此修改也不破坏二叉排序树的特性。

若*p结点的左子树和右子树均不空。在删去*p之后,为保持其它元素之间的相对位置不变,可按中序遍历保持有序进行调整,可以有两种做法:

i.其一是令*p的左子树为*f的左/右(依*p是*f的左子树还是右子树而定)子

树,*s为*p左子树的最右下的结点,而*p的右子树为*s的右子树;

ii.其二是令*p的直接前驱(或直接后继)替代*p,然后再从二叉排序树中删去它的直接前驱(或直接后继)-即让*f的左子树(如果有的话)成为*p

左子树的最左下结点(如果有的话),再让*f成为*p的左右结点的父结点。 void Release(Node *node); //释放结点空间

后序遍历删除以node为根结点的树的所有结点空间。

void Show(Node *node); //打印树结点值函数

中序遍历树,打印每个结点的值。

相关文档
最新文档