数据结构与算法之 树
二叉搜索树的使用
//这一个版本写的是较为简单的树,分为了三个部分组成,
主要是利用栈的思想来进行前序遍历我们的树,本程序没有采用递归去前序遍历,用递归的话效率过低,不推荐使用.//本程序所实现的功能有
//插入元素(必须小于栈的最大容量). 前序遍历 二叉搜索树的删除(必须小于当前树内元素的个数) .再次前序遍历 .查找指定节点
teer.h#pragma once#define MAX_NODE 1024
typedef int ElemeType;typedef struct _Bnode {ElemeType data; //元素类型struct _Bnode *lchild, *rchild; //指向左右孩子结点
}Bnode, Btree;
stack.h#pragma once
#include<stdlib.h>
#include<stdio.h>
#include"tree.h"#define MaxSize 128 //预分配空间, 这个数值根据实际大小预估确定typedef struct _SqStack {Bnode *base; //栈底指针Bnode *top; //栈顶指针
}SqStack;//构造一个空栈S
bool InitStack(SqStack &S) { S.base = new Bnode[MaxSize]; //为栈分配最大容量if (!S.base) return false; //空间分配失败S.top = S.base; //top初始化为base,空栈return true;
}
//插入元素e为新的栈顶元素
bool PushStack(SqStack &S, Bnode e) {if (S.top - S.base == MaxSize)return false; //栈满*(S.top++) = e;return true;}
//删除S的栈顶元素,暂存在变量e
bool PopStack(SqStack &S, Bnode &e) {if (S.base == S.top)return false; //栈空e = *(--S.top);return true;
}
//返回S的栈顶元素,栈顶指针不变
Bnode *GetTop(SqStack &S) {if (S.top != S.base) { //栈非空return S.top - 1; //返回栈顶元素的值,栈顶指针不变} else { //这种情况是栈空的状况return NULL;}
}
//返回栈中元素个数
int GetSize(SqStack &S) {return(S.top - S.base);
}
//判断栈是否为空
bool IsEmpty(SqStack &S) {if (S.top == S.base) {return true;} else {return false;}
}
//销毁栈
void DestroyStack(SqStack &S) {if (S.base) {free(S.base);S.base = NULL;S.top = NULL;}
}
tree.cpp//1.插头 2. 全插 3.前序遍历 4.二叉搜索树的删除 5.再次前序遍历 6.查找指定节点
#include<iostream>
#include<Windows.h>
#include"stack.h"using namespace std;
static int length = 0;//插入元素
bool InsertBnode(Btree* &root, Bnode* node) {Btree *tmp=NULL, *parent = NULL;;if (!node) return false; //待插入的节点为空时,直接就返回//将待插入的节点的左右后指针清空,为了以后的插入做准备node->lchild = NULL;node->rchild = NULL;//如果没有根节点那么,根节点的值就等于要插入结点的值if (root->data == NULL) {root->data = node->data;length++;return true;}//再有根节点的情况下tmp = root; //先让这个临时指针指向我们的根结点,代替我们的根节点移动从而去和要插入结点比较while (tmp) { //遍历能比较的点,知道tmp指向的结点的左右子节点都不存在为止parent = tmp; //让parent 充当现在的父节点,tmp就能继续向下实现遍历了if (node->data > parent->data) { //当要插入结点大于我们的父节点时tmp继续向下遍历tmp = tmp->rchild;} else { //当要插入结点小于我们的父节点时tmp继续向下遍历tmp = tmp->lchild;}}//现在已经到了最后的结点了,现在比较带插入结点和这个parent结点哪个大就能确定待插入结点的位置if (node->data > parent->data) { //待插入结点大于父节点 放右边parent->rchild = node;} else { //待插入结点小于父节点 放左边parent->lchild= node;}length++;return true;
}
//前序遍历
void proprint(Btree* root) {Btree tmp;SqStack stack;InitStack(stack);PushStack(stack, *root); //根节点进栈while (!(IsEmpty(stack))) { //栈为空,所有节点均已处理 PopStack(stack, tmp); //要遍历的节点 printf("- %d -", tmp.data); //打印要便利的节点的值if (tmp.rchild != NULL) {PushStack(stack, *(tmp.rchild)); //右子节点先入栈,后处理 }if (tmp.lchild != NULL) {PushStack(stack, *(tmp.lchild)); //左子节点后入栈,接下来先 处理 }}DestroyStack(stack); //将我们的之前创建好的栈销毁掉
}//寻找二叉搜索树左子树上最大的结点 int findMax(Btree* root) {//方式二 采用循环 while(root->rchild){ root = root->rchild; }return root->data;
}//删除指定元素
Btree* DeleteNode(Btree* root, int key) {if (root == NULL) return NULL;//没有找到删除节点 if (root->data > key) {root->lchild = DeleteNode(root->lchild, key);return root;}if (root->data < key) {root->rchild = DeleteNode(root->rchild, key);return root;}//删除节点不存在左右子节点,即为叶子节点,直接删除 if (root->lchild == NULL && root->rchild == NULL) {length--;return NULL;}//删除节点只存在右子节点,直接用右子节点取代删除节点 if (root->lchild == NULL && root->rchild != NULL) {length--;return root->rchild;}//删除节点只存在左子节点,直接用左子节点取代删除节点 if (root->lchild != NULL && root->rchild == NULL){length--;return root->lchild;
}//删除节点存在左右子节点,直接用左子节点最大值取代删除节点int val = findMax(root->lchild);root->data=val; root->lchild = DeleteNode(root->lchild,val); length--;return root;
}/** * 使用非递归方式查找结点 */
bool QueryByLoop(Bnode* root, int Element) { while (root != NULL && root->data!= Element) {if (Element <root->data) {root = root->lchild; } else { root = root->rchild; }}if (root == NULL) {return false;} else {return true;}}int main(void) {Btree *s=new Btree;s->lchild = s->rchild = NULL;s->data = NULL;Bnode *node;//将第一个数据插入到树作为根节点node = new Bnode;cout << "请输入你想要入树的元素个数(不得超过本栈的最大容量: " << MaxSize << "): ";int num=-1;cin >> num;//不让用户输入的值超过栈的最大容量while (1) {if (num > MaxSize) {cout << "输入的个数超过了本栈的最大容量,请重新输入!!!! ";cout << "请输入你想要入树的元素个数(不得超过本栈的最大容量: " << MaxSize << "): ";cin >> num;} else {break;}}//插入头结点cout << "请输入你想要插入的元素: ";cin>>node->data;if(InsertBnode(s, node)) {cout << "插入元素 " << node->data << "成功! " << endl;} else {cout << "插入元素失败! " << endl;}for (int i = 1; i < num; i++) {node = new Bnode;cout << "请输入你想要插入的元素: ";cin >> node->data;if (InsertBnode(s, node)) {cout << "插入元素 " << node->data << "成功! " << endl;;} else {cout << "插入元素失败! " << endl;}}//前序遍历树proprint(s);cout << "一共有 " << length << " 个元素" << endl;//二叉搜索树的删除cout << "请输入你要删除的元素的个数(不能超过现在的树的最大个数: " << length << "): ";int Element;cout << endl;cin >> num;while (1) {if (num > length) {cout << "输入的个数超过了本栈的最大容量,请重新输入!!!! ";cout << "请输入你想要入树的元素个数(不得超过本栈的最大容量: " << length << "): ";cin >> num;} else {break;}}for (int i = 0; i < num; i++) {cout << "请输入你想删除的值: ";cin >> Element;DeleteNode(s, Element);cout << "***********************************************" << endl;proprint(s);cout << "一共有 " << length << " 个元素)" << endl;cout << "***********************************************" << endl;}cout << "请输入你想要查找的值: " << endl;cin >> Element;if (QueryByLoop(s, Element)) {cout << "查找成功!! 查找的值是: " << Element << endl;} else {cout << "查找失败!不存在这个值" << endl;}proprint(s);cout << "一共有 " << length << " 个元素" << endl;system("pause");return 0;
}
数据结构与算法之 树相关推荐
- 数据结构与算法——AVL树类的C++实现
关于AVL树的简单介绍能够參考: 数据结构与算法--AVL树简单介绍 关于二叉搜索树(也称为二叉查找树)能够參考:数据结构与算法--二叉查找树类的C++实现 AVL-tree是一个"加上了额 ...
- 数据结构与算法--B树原理及实现
B树 前几篇文中讨论的数据结构我们都是假设所有的数据都存储在计算机的主存中.可说总要那么海量的数据需要通过个中数据结构去存储,我们不可能有这么多内存区存放这些数据.那么意味着我们需要将他们放磁盘.所以 ...
- 《数据结构与算法》——树与二叉树之遍历总结
<数据结构与算法>--树与二叉树之遍历总结 树与二叉树部分计划分为三次进行复习总结,第一次为基本概念和二叉树的遍历,第二次内容为线索二叉树以及树和森林,第三次为树与二叉树的应用. 目录 & ...
- 数据结构与算法(3)——树(二叉、二叉搜索树)
前言:题图无关,现在开始来学习学习树相关的知识 前序文章: 数据结构与算法(1)--数组与链表(https://www.jianshu.com/p/7b93b3570875) 数据结构与算法(2)-- ...
- 高级数据结构与算法 | AVL树 (高度平衡树)
文章目录 AVL树 实现思路 数据结构 查找 平衡因子 旋转 右旋 左旋 右左双旋 左右双旋 插入 删除 AVL树的验证 中序遍历 平衡判断 AVL树的性能 完整代码实现 AVL树 AVL树是最先发明 ...
- 数据结构与算法:树与二叉树python实现
最近复习一遍数据结构与算法,做一些笔记,大家可以一起复习. 一.树的一些容易混淆的定义: 结点层:根结点的层定义为1:根的孩子为第二层结点,依此类推: 树的深度(或高度):树中最大的结点层: 满二叉树 ...
- 数据结构和算法——kd树
一.K-近邻算法 K-近邻算法是一种典型的无参监督学习算法,对于一个监督学习任务来说,其 m m个训练样本为: {(X(1),y(1)),(X(2),y(2)),⋯,(X(m),y(m))} \lef ...
- 高级数据结构与算法 | B树、B+树、B*树
文章目录 搜索结构 B树 B树的插入 B树的遍历 B树的性能 B+树 B+树的插入 B+树的遍历 B*树 B*树的插入 总结 搜索结构 如果我们有大量的数据需要永久存储,就需要存储到硬盘之中,但是硬盘 ...
- 数据结构与算法6—树
树 树的表示方式有 树形图表示法:逻辑结构描述直观 嵌套集合表示法(文氏图表示法) 凹入表示法 广义表表示法 二叉树 二叉树是另一种重要的树形结构,是度为2的有序树,它的特点是每个结点至多有两棵子树. ...
- C++数据结构与算法(九) 树,优先级队列,最大堆的实现
树: 用来表示具有结构层次的数据,应用: 软件工程技术:模块化技术 根: 子树: 在树中,每个元素都代表一个节点. 树的级: 根是一级,根的孩子是二级,一次往下,有三级,四级... 树的高度(深度): ...
最新文章
- asp java 变量_ASP_用stack变量优化Java代码, java程序包含了大量的对象 - phpStudy...
- HDU1163 Eddy's digital Roots(解法二)【快速模幂+九余数定理】
- json解析 子类和父类同名属性如何赋值_想学变量的解构赋值?看完这一篇就够了...
- 会计记忆总结之五:会计账薄
- [BUUCTF-pwn]——wdb_2018_2nd_easyfmt
- java中HashMap遍历详解
- 软件测试第4周小组作业:WordCount优化
- [资料]PHP中的__set __get使用
- html背景图片垂直居中,css — 定位、背景图、水平垂直居中
- JAVA——孪生素数
- Timus 1741
- plupload踩坑小结
- 【原创】objdump 的使用
- 零售商店销售管理系统——第四周
- Layui Form 如何主动验证表单是否通过
- Pr 入门系列之十四:导出
- 2022-03-27 screenX和clientX的区别以及offsetX和pageX的区别
- 数理逻辑与集合论复习脉络
- 远程渗透登陆他人电脑
- 【风电功率预测】麻雀算法优化BP神经网络风电功率预测【含Matlab源码 1319期】