二叉排序树 C++
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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); //打印树结点值函数
中序遍历树,打印每个结点的值。