二叉树
BinaryTree.h
/**
* @Author : zhang
* @create 2022/3/10 17:21
*/
#ifndef PRACTICE_BINARYTREE_H
#define PRACTICE_BINARYTREE_H
#include "string"
using namespace std;
struct BTNode{
char data;//保存结点数值
BTNode* leftChild;
BTNode* rightChild;
BTNode(char c){
this->data=c;
}
};
typedef BTNode* BiTree;
class BinaryTree {
private:
BiTree root;
public:
// BiTree root;
// BinaryTree(BiTree &T);
BinaryTree();
void visit(BTNode* T);
BiTree CreateBiTree(int& position,string str);
void CreateBiTree(BiTree &T) ;
void PreOrder(BiTree T);
void InOrder(BiTree T);
void PostOrder(BiTree T);
BiTree& getRoot() ;
};
#endif //PRACTICE_BINARYTREE_H
BinaryTree.cpp
/**
* @Author : zhang
* @create 2022/3/10 17:21
*/
#include "BinaryTree.h"
#include "iostream"
using namespace std;
/*
* @Description 输出结点信息
*/
void BinaryTree::visit(BiTree T) {
cout<<T->data<<" ";
}
/*
* @Description 创建二叉树
*
* 返回的是新建二叉树根结点的指针
*
* while (cin>>str){
int position=0;//标记字符串处理位置
binaryTree.setRoot(binaryTree.CreateBiTree(position,str));
binaryTree.PostOrder(binaryTree.getRoot());
cout<<endl;
}
*
*/
BiTree BinaryTree::CreateBiTree(int& position,string str){
//从字符串中获取结点值
char c=str[position++];
if (c=='#'){
return nullptr;
}
BiTree tree=new BTNode(c);//创建根结点,这里对结点的赋值过程在构造函数中完成
tree->leftChild= CreateBiTree(position,str);//创建左子树
tree->rightChild= CreateBiTree(position,str);//创建右子树
return tree;
}
/*
* @Description 先序遍历
*
* 这里的T是根结点的指针
*/
void BinaryTree::PreOrder(BiTree T) {
if(T!= nullptr){
visit(T);
PreOrder(T->leftChild);
PreOrder(T->rightChild);
}
}
/*
* @Description 中序遍历
*
* 这里的T是根结点的指针
*/
void BinaryTree::InOrder(BiTree T) {
if(T!= nullptr){
InOrder(T->leftChild);
visit(T);
InOrder(T->rightChild);
}
}
/*
* @Description 后序遍历
*
* 这里的T是根结点的指针
*/
void BinaryTree::PostOrder(BiTree T) {
if(T!= nullptr){
PostOrder(T->leftChild);
PostOrder(T->rightChild);
visit(T);
}
}
/*
* @Description 新建二叉树
*
*
*
*/
void BinaryTree::CreateBiTree(BiTree &T) {
char item;
cin>>item;
if(item=='#'){
T= nullptr;
}else{
T=new BTNode(item);
CreateBiTree(T->leftChild);
CreateBiTree(T->rightChild);
}
}
/*
* @Description 构造函数
*/
BinaryTree::BinaryTree() {
this->root= nullptr;
}
BiTree& BinaryTree::getRoot() {
return this->root;
}
线索二叉树
ThreadTree.h
/**
* @Author : zhang
* @create 2022/3/11 16:52
*/
#ifndef PRACTICE_THREADTREE_H
#define PRACTICE_THREADTREE_H
/*
* @Description 线索树结点
*
* tag为1表示线索,为0表示子树
*/
struct ThreadTreeNode{
char data;
ThreadTreeNode* leftChild;
ThreadTreeNode* rightChild;
int ltag,rtag;//左右线索标志
};
typedef ThreadTreeNode* ThTree;
ThTree pre= nullptr;//全局变量pre,指向当前访问结点的前驱
/*
* @Description 线索二叉树
*
*
*/
class ThreadTree {
private:
ThTree root;
public:
void InThread(ThTree T);
void visit(ThTree T);
void CreateBiTree(ThTree &T);
void CreateInThread(ThTree &T);
ThTree firstNode(ThTree p);
ThTree nextNode(ThTree p);
ThTree lastNode(ThTree p);
ThTree preNode(ThTree p);
void revInorder(ThTree p);
void inorder(ThTree T);
};
#endif //PRACTICE_THREADTREE_H
ThreadTree.cpp
/**
* @Author : zhang
* @create 2022/3/11 16:52
*/
#include "ThreadTree.h"
#include "iostream"
using namespace std;
/*
* @Description 中序遍历二叉树,一边遍历,一边线索化
*
* 对结点中序遍历
*/
void ThreadTree::InThread(ThTree T) {
if(T!= nullptr){
InThread(T->leftChild);
visit(T);//对结点进行线索化
InThread(T->rightChild);
}
}
/*
* @Description 对结点的访问并非输出其值,而是对结点赋值,进行线索化
*/
void ThreadTree::visit(ThTree T) {
if (T->leftChild== nullptr){
T->leftChild=pre;
T->ltag=1;
}
if (pre!= nullptr && pre->rightChild == nullptr){
pre->rightChild=T;
pre->rtag=1;
}
pre=T;
}
/*
* @Description 中序线索化二叉树T
*/
void ThreadTree::CreateInThread(ThTree &T) {
pre= nullptr;//pre初始为nullptr
if (T!= nullptr){//非空二叉树才能线索化
InThread(T);//中序线索化二叉树
if (pre->rightChild== nullptr){
pre->rtag=1;//处理遍历的最后一个结点
}
}
}
/*
* @Description 建立二叉树,并为结点赋值
*
*/
void ThreadTree::CreateBiTree(ThTree &T) {
char item;
cin>>item;
if(item=='#'){
T= nullptr;
}else{
T->data=item;
CreateBiTree(T->leftChild);
CreateBiTree(T->rightChild);
}
}
/*
* @Description 找到以p为根的子树中,第一个被中序遍历的结点
*/
ThTree ThreadTree::firstNode(ThTree p) {
//循环找到最左下结点(不一定是叶结点)
while (p->ltag==0){
p=p->leftChild;
}
return p;
}
/*
* @Description 在中序线索二叉树中找到结点p的后继结点
*/
ThTree ThreadTree::nextNode(ThTree p) {
if (p->rtag==0){
return firstNode(p->rightChild);
}else{
return p->rightChild;
}
}
/*
* @Description 对中序线索二叉树进行中序遍历
*
* 空间复杂度为O(1)
*/
void ThreadTree::inorder(ThTree T) {
for (ThTree p= firstNode(T) ; p!= nullptr ; p= nextNode(p)) {
cout<<p->data<<endl;
}
}
/*
* @Description 找到以p为根的子树中,最后一个被中序遍历的结点
*/
ThTree ThreadTree::lastNode(ThTree p) {
while (p->rtag==0){//循环到最右下结点(不一定是叶结点)
p=p->rightChild;
}
return p;
}
/*
* @Description 在中序线索二叉树中找到结点p的前驱结点
*/
ThTree ThreadTree::preNode(ThTree p) {
//左子树中最右下结点
if (p->ltag==0){
return lastNode(p->leftChild);
}else{
return p->leftChild;//ltag==1直接返回前驱线索
}
}
/*
* @Description 对中序线索二叉树进行逆向中序遍历
*/
void ThreadTree::revInorder(ThTree p) {
for(ThTree t= lastNode(p);t!= nullptr;t= preNode(t)){
cout<<t->data<<endl;
}
}
二叉搜索树
BinarySearchTree.h
/**
* @Author : zhang
* @create 2022/3/13 17:11
*/
/*
* @Description 二叉搜索树
*
*
*/
#ifndef PRACTICE_BINARYSEARCHTREE_H
#define PRACTICE_BINARYSEARCHTREE_H
struct BSTNode{
int key;
BSTNode* leftChild;
BSTNode* rightChild;
};
typedef BSTNode* BSTree;
class BinarySearchTree {
private:
BSTree root;
public:
BSTree search1(BSTree T,int key);
BSTree search2(BSTree T,int key);
void visit(BSTree T);
int insert(BSTree &T,int k);
void creat(BSTree &T,int str[],int n);
const BSTNode *getRoot() const;
void setRoot( BSTNode *root);
};
#endif //PRACTICE_BINARYSEARCHTREE_H
BinarySearchTree.cpp
/**
* @Author : zhang
* @create 2022/3/13 17:11
*/
#include "BinarySearchTree.h"
#include "iostream"
using namespace std;
/*
* @Description 在二叉搜索树T中查询关键值为key的元素
*
* 最坏空间复杂度:O(1)
*/
BSTree BinarySearchTree::search1(BSTree T, int key) {
//若树为空或等于根结点值
while (T!= nullptr && key!=T->key){
if(key<T->key){
T=T->leftChild;
}else{
T=T->rightChild;
}
}
return T;
}
/*
* @Description 在二叉搜索树T中查询关键值为key的元素(递归实现)
*
* 最坏空间复杂度:O(h)
*/
BSTree BinarySearchTree::search2(BSTree T, int key) {
if(T== nullptr){//查找失败
return nullptr;
}
if(key==T->key){//查找成功
return T;
}else if(key<T->key){//在左子树中找
return search2(T->leftChild,key);
}else{//在右子树中找
return search2(T->rightChild,key);
}
}
const BSTNode *BinarySearchTree::getRoot() const {
return root;
}
void BinarySearchTree::setRoot( BSTNode *root) {
BinarySearchTree::root = root;
}
/*
* @Description 输出结点值
*/
void BinarySearchTree::visit(BSTree T) {
cout<<T->key<<endl;
}
/*
* @Description 在BST中插入关键值为K的新结点(递归实现)(建立过程)
*
* 这里的行参为引用类型哟
*
* 最坏空间复杂度:O(h)
*
* 新插入的结点一定是叶子结点
*/
int BinarySearchTree::insert(BSTree &T, int k) {
if (T== nullptr){//原树为空,新插入的结点为根结点
T=new BSTNode();
T->key=k;
T->leftChild= nullptr;
T->rightChild= nullptr;
return 1;//返回1,插入成功
}else if(k==T->key){//存在关键字相同的结点,插入失败
return 0;
}else if(k<T->key){//插到左子树
return insert(T->leftChild,k);
}else{//插到右子树
return insert(T->rightChild,k);
}
}
/*
* @Description 创建BST
*
* 不同的关键字序列可能得到不同的BST
*
* str:关键字序列
* n:关键字个数
*
*/
void BinarySearchTree::creat(BSTree &T, int *str, int n) {
T= nullptr;
int i=0;
while (i<n){
insert(T,str[i]);
i++;
}
}