首页 > 编程语言 >C++ 二叉树 家谱

C++ 二叉树 家谱

时间:2023-11-26 10:44:20浏览次数:37  
标签:me cout -- C++ st BTNode 家谱 二叉树 NULL

实验三 树 家谱 文档

实验说明

要求完成的功能如下,测试输出如图 所示:
(1) 输入一棵二叉树的括号表示法,完成树的构建
(2) 使用后序遍历递归算法遍历二叉树并输出
(3) 使用先序遍历非递归算法遍历二叉树并输出
(4) 指定家谱中的某一成员,输出其所有长辈
测试例:
输入:A(B(C(E,F),D(G(M,N),H)),)
输出:
M 的长辈为:FCNGHDBA
N 的长辈为:HDBA


流程图

以下为该实验的流程图

graph TD A[输入括号表达式] --> B((表达式正确)) -- yes -->H[生成二叉树] --> C[输出] C --> D[输入成员] D --> E((是否存在)) E -- yes --> F[输出其祖先] E -- no --> G F --> G[结束] B -- no --> G

BTree.h

树的结点

//树的结点
typedef struct node//家谱中个人信息的载体
{
	char data;
	bool isLchild;
	int level;
	struct node* lchild;
	struct node* rchild;
}Node,*BTNode;//struct node -> Node/*BTNode

树的类

class BTree
{
private:
	BTNode root;    //根结点
public:
	BTree(const char* str);  //构造方法
	~BTree();  //析构方法
	bool isEmpty();
	BTNode getRoot();
	void PostOrderRe(BTNode b); //后序递归遍历
	void PreOrderRe(BTNode b); //先序递归遍历,由后序遍历简单变化而来 
	void PreOrderNotRe();    //先序非递归遍历
	bool isAncestor(BTNode b, char me);
	BTNode FindMe(char me);
	BTNode FindFather(BTNode me);
	void FindAllAncestor(char Object);
	void ShowAncestor(BTNode ancestor);
	void DestroyBTree(BTNode b);
	bool banish(char b);  //逐出家门,我闲着无聊搞得,不属于课程要求
};

源.cpp

菜单

int main(void)
{
	int choose; 
	char housemenu[100];
	char me;
	cout << "请以括号表示法输入二义树结构:";
	cin >> housemenu;
	BTree tree(housemenu); //构造BTree类的对象
	BTNode r = tree.getRoot();
	cout << "后序遍历递归算法输出:";
	tree.PostOrderRe(r);
	cout << endl<<"前序遍历递归算法输出:";
	tree.PreOrderNotRe();
	cout <<endl<< "请输入指定人物代号,以查询其所有长辈:";
	cin >> me;
	cout << me << "的所有长辈为:";
	tree.FindAllAncestor(me);
	cout << endl << "请输入指定人物代号,以查询其所有同辈:";
	cin >> me;
	BTNode me_BTnode = tree.FindMe(me);
	if (me_BTnode == NULL) {
		cout << "没有此人" << endl;
	}
	else {
		cout << me << "的所有同辈为:";
		tree.ShowAncestor(me_BTnode);
	}
	cout <<endl<< "是否需要进行逐出操作(1-是/0-否):";
	cin >> choose;
	if (choose == 0) {
		return 0;
	}
	cout<< "请输入将被逐出家族的支系的族长:";
	cin >> me;
	me_BTnode = tree.FindMe(me);
	if (me_BTnode == NULL) {
		cout << "没有此支系" << endl;
	}
	else {
		cout << "该支系家谱为:";
		tree.PreOrderRe(me_BTnode);
		cout <<endl<< "是否要逐出此支系(1-是/0-否):";
		cin >> choose;
		if (choose == 1) {
			cout << "是否真的要逐出此支系(1-是/0-否):";
			cin >> choose;
			if (choose == 1) {
				if (tree.banish(me)) {
					cout << "逐出后新家谱为:";
					tree.PostOrderRe(r);
				}
				else {
					cout << "逐出失败";
				}
			}
		}
	}


	return 0;
}

BTree.cpp

树的初始化

BTree::BTree(const char* str)
{
	stack<BTNode> st;
	BTNode p;
	bool flag = true;  //flag默认为true,左结点
	int i = 0;
	while (str[i] != '\0') {
		switch (str[i]) {
		case'(':       // '( ' => p的孩子,
			st.push(p);   
			flag = true;   //例子:B为左结点,A(B,C)
			break;
		case')':    
			st.pop();
			break;
		case',':
			flag = false; //C为右结点
			break;
		default:;
			p = new Node;  //新的结点
			p->data = str[i];
			p->lchild = NULL;  //一定要记得加上,我掉在这坑里好久
			p->rchild = NULL;
			if (root == NULL) {   //空树
				p->isLchild = true;
				p->level = 1;       //树的高度,根结点在第一层
				root = p;
			}
			else {
				if (!st.empty()) {
					p->level += st.top()->level;  //高度+1
					if (flag) {
						st.top()->lchild = p;
						p->isLchild = true;
					}
					else if (!st.empty()) {
						st.top()->rchild = p;
						p->isLchild = false;
					}
				}
			}
		}
		i++;
	}
}

后序遍历输出

void BTree::PostOrderRe(BTNode b)
{
	if (b->lchild != NULL || b->rchild != NULL) {
		cout << "(";
		if (b->lchild != NULL) {
			PostOrderRe(b->lchild);
		}
		if (b->rchild != NULL) {
			cout << ",";
			PostOrderRe(b->rchild);
		}
		cout << ")";
	}
	cout << b->data;  //将这句换一下位置即为先序遍历
	return;
}

先序非遍历输出

void BTree::PreOrderNotRe()
{
	stack<BTNode> st;
	BTNode p;
	p = root;
	while (!st.empty() || p != NULL) {
		if (p != NULL) {
			cout << p->data;
			st.push(p);
			p = p->lchild;
		}
		else {
			p=st.top();
			st.pop();
			p = p->rchild;
		}
	}
	return;
}

找祖先

void BTree::ShowAncestor(BTNode ancestor) 
{
	stack<BTNode> st;
	BTNode p;
	p = root;
	while (!st.empty() || p != NULL) {
		if (p != NULL) {
			if (p->level == ancestor->level&&p!=ancestor) {
				cout << p->data;
			}
			st.push(p);
			p = p->lchild;
		}
		else {
			p = st.top();  //取栈顶的结点,没出栈
			st.pop();    //出栈
			p = p->rchild;
		}
	}
	return;
}

收尾

源码

我的github仓库
我的gitee仓库https://gitee.com/aa2255/smalltask

其余的方法基本都是根据已有的变化一下就行了,全部贴出来太长了,影响观感(主要是我懒 -_- )。
就到这了,青山不改水长流,后会有期。

标签:me,cout,--,C++,st,BTNode,家谱,二叉树,NULL
From: https://www.cnblogs.com/abcd1314/p/17856601.html

相关文章

  • C++ 通过SQLite实现命令行工具
    本文介绍了一个基于C++、SQLite和Boost库的简单交互式数据库操作Shell。该Shell允许用户通过命令行输入执行各种数据库操作,包括添加、删除主机信息,设置主机到特定主机组,以及显示主机和主机组列表。通过调用SQLite3库实现数据库连接和操作,以及使用Boost库进行字符串解析......
  • 试题 D: 本质上升序列(C/C++)
    题目描述:小蓝特别喜欢单调递增的事物。在一个字符串中,如果取出若干个字符,将这些字符按照在字符串中的顺序排列后是单调递增的,则成为这个字符串中的一个单调递增子序列。例如,在字符串lanqiao中,如果取出字符n和q,则nq组成一个单调递增子序列。类似的单调递增子序列还有lnq......
  • C#调用C++类库的几种方式
    1、 直接调用C++类库中的公共方法使用DllImport特性对方法进行调用,比如一个C++类库SampleCppWrapper.dll中的公共方法:extern"C"__declspec(dllexport)int__stdcallAdd(intn1,intn2);__stdcall表示调用约定:参数都是从右向左通过堆栈传递, 函数调用在返回前要由被调......
  • C/C++ 通过SQLiteSDK增删改查
    SQLite,作为一款嵌入式关系型数据库管理系统,一直以其轻量级、零配置以及跨平台等特性而备受青睐。不同于传统的数据库系统,SQLite是一个库,直接与应用程序一同编译和链接,无需单独的数据库服务器进程,实现了数据库的零配置管理。这种设计理念使得SQLite成为许多嵌入式系统、移动应用和......
  • c++ 为什么引入函数对象?
    C++引入函数对象主要是因为函数对象具有以下优势:函数对象可以有自己的状态:我们可以在类中定义状态变量,这样一个函数对象在多次的调用中可以共享这个状态。但是函数调用没这种优势,除非它使用全局变量来保存状态。函数对象有自己特有的类型,而普通函数无类型可言:这种特性对......
  • C++回调函数的定义和调用
    文章目录一、C++回调函数1.C/C++回调函数2.普通回调3.函数指针4.C++类的静态函数作为回调函数5.类的非静态函数作为回调函数6.Lambda表达式作为回调函数7.std::funtion和std::bind的使用二、其他参考资料 一、C++回调函数C++回调函数1.C/C++回调......
  • 十七、C++字符串(二)
    十七、C++字符串(二)1、字符串的应用需求:设计一个程序,用户输入属性id或者pass或者role可以把对应的内容显示出来,给定字符串如下:stringstr{"id=user;pass=632105;role=郝英俊;"};//设计一个程序,用户输入属性id或者pass或者role可以把对应的内容显示出来#include<iostream>......
  • 新手VSCode配置C++20
    最近买了本C++20的书,想要自己配置下在VScode的环境例子代码:#include<iostream>#include<format>intmain(){std::cout<<std::format("Hello,world!{0}",123)<<std::endl;//输出:Hello,world!123std::stringstr=std::format("......
  • C/C++ 运用Npcap发送UDP数据包
    Npcap是一个功能强大的开源网络抓包库,它是WinPcap的一个分支,并提供了一些增强和改进。特别适用于在Windows环境下进行网络流量捕获和分析。除了支持通常的网络抓包功能外,Npcap还提供了对数据包的拼合与构造,使其成为实现UDP数据包发包的理想选择。本章将通过Npcap库构造一......
  • C++ Boost 异步网络编程基础
    Boost库为C++提供了强大的支持,尤其在多线程和网络编程方面。其中,Boost.Asio库是一个基于前摄器设计模式的库,用于实现高并发和网络相关的开发。Boost.Asio核心类是io_service,它相当于前摄模式下的Proactor角色。所有的IO操作都需要通过io_service来实现。在异步模式下,程序除了发起......