二叉树的数据保存方式主要是数组和链表,如果使用完全二叉树数组更适合,负责适合使用链表保存。数据读取分为前序、中序、后序,主要以父节点来区分,前序则先父节点、左子节点、右子节点;中序则先左子节点、父节点、右子节点;后序则左子、右子、中。
#include
#include
using namespace std;
// 定义二叉树
typedef struct CSNode {
int data;
CSNode* left = NULL, * right = NULL;
}CSNode, * CSTree;
class DbTree {
private:
CSNode* lastTree = NULL;
CSNode node; // 好的吧,我这里是不是应该也用指针的
bool haveHead = false; // 定义是否有文件,完全没有则为false
CSNode* tree = NULL;
vector pointLink;
vector vct;
vector orderlyVct;
void left(CSNode* currentTree = NULL);
void center(CSNode* currentTree = NULL);
void right(CSNode* currentTree = NULL);
public:
DbTree(int x) {
node.data = x;
tree = &node;
haveHead = true;
}
void add(int x, CSNode* currentTree = NULL);
bool remove(int x, CSNode* currentTree = NULL);
void removeAll(CSNode* currentTree = NULL); // 全部删除,本来我是觉得可以用后序遍历一次全部删除的,但是我懒
void leftShow();
vector centerShow(); // 中序会是从小到大,我可以直接输出使用
void rightShow();
void balance(); // 平衡二叉树,将二叉树平衡排序
};
int main()
{
DbTree dbTree(100);
dbTree.add(50);
dbTree.add(122);
dbTree.add(60);
dbTree.add(55);
dbTree.add(65);
dbTree.add(70);
cout << "left is :" << endl;
dbTree.leftShow();
cout << "rihgt is :" << endl;
dbTree.rightShow();
cout << "center is :" << endl;
dbTree.centerShow();
dbTree.remove(60);
cout << "删除完成" << endl;
dbTree.leftShow();
dbTree.removeAll();
cout << "全部删除后" << endl;
dbTree.centerShow();
int i = 1;
int j;
while (i)
{
cin >> i;
if (i == 1) {
cin >> j;
dbTree.add(j);
}
if (i == 2) {
cin >> j;
dbTree.remove(j);
}
if (i == 3)
{
cout << "显示一波" << endl;
dbTree.centerShow();
}
}
return 0;
}
void DbTree::add(int x, CSNode* currentTree) {
if (currentTree == NULL)
currentTree = &node;
// 如果是首次添加添加,则将设为二插树头文件
if (!haveHead)
{
haveHead = true;
node.data = x;
}
else {
//tree = &node;
// 如果比当前值小,在左边添加,负责在右边添加
if (x < currentTree->data) {
if (currentTree->left == NULL)
{
CSNode* lastTree;
lastTree = currentTree;
currentTree = new CSNode;
currentTree->data = x;
lastTree->left = currentTree;
}
else {
currentTree = currentTree->left;
add(x, currentTree);
}
}
else if (x > currentTree->data)
{
if (currentTree->right == NULL)
{
CSNode* lastTree;
lastTree = currentTree;
currentTree = new CSNode;
currentTree->data = x;
lastTree->right = currentTree;
}
else {
currentTree = currentTree->right;
add(x, currentTree);
}
}
}
}
bool DbTree::remove(int x, CSNode* currentTree) {
if (haveHead) {
if (currentTree == NULL)
{
lastTree = &node;
currentTree = &node;
}
//tree = &node;
CSNode* deleteTree = currentTree;
if (x == currentTree->data) {
// 删除当前树,并且如果有子二叉树,讲子二叉树重新排序
if (currentTree->left != NULL && currentTree->right != NULL) {
// 将父节点的替换的子节点方向指向子节点的右边子节点,子节点的左边子节点并到右边子节点的最左边
if (x != node.data) {
if (lastTree->left == currentTree)
lastTree->left = currentTree->right;
else
lastTree->right = currentTree->right;
}
lastTree = currentTree->left;
currentTree = currentTree->right;
while (currentTree->left != NULL)
{
currentTree = currentTree->left;
}
currentTree->left = lastTree; // 将删除后的点的左下角点保存
}
else if (currentTree->left == NULL && currentTree->right == NULL) {
if (x != node.data)
if (lastTree->left == currentTree)
lastTree->left = NULL;
else
lastTree->right = NULL;
else {
haveHead = false;
}
}
else {
// 将父的链接指向自己的子
if (x != node.data)
{
if (lastTree->left == currentTree)
if (currentTree->left != NULL)
lastTree->left = currentTree->left;
else
lastTree->left = currentTree->right;
else
if (currentTree->left != NULL)
lastTree->right = currentTree->left;
else
lastTree->right = currentTree->right;
}
}
// 如果删除的父节点是第一个
if (x == node.data) {
if (deleteTree->right != NULL) {
node.data = deleteTree->right->data;
node.left = deleteTree->right->left;
node.right = deleteTree->right->right;
}
else if (deleteTree->left != NULL) {
node.left = deleteTree->left->left;
node.right = deleteTree->left->right;
node.data = deleteTree->left->data;
}
}
else
delete deleteTree;
return true; // 返回执行成功,并且不继续一下循环
}
lastTree = currentTree;
// 如果比当前值小,在左边添加,负责在右边添加
if (x < currentTree->data) {
if (currentTree->left == NULL)
{
return false;
}
else {
currentTree = currentTree->left;
remove(x, currentTree);
}
}
else {
if (currentTree->right == NULL)
{
return false;
}
else {
currentTree = currentTree->right;
remove(x, currentTree);
}
}
}
}
// 复制后续遍历,将原来用于显示的地方用于删除
void DbTree::removeAll(CSNode* currentTree) {
if (haveHead)
{
// 所有二叉树排序获取,可以这样暴力一波
/*vector thisVct;
thisVct = centerShow();
for(int i = 0; i < thisVct.size(); i++){
remove((int)thisVct[i].data);
}/**/
// 从起点开始
if (currentTree == NULL)
currentTree = &node;
if (currentTree->left != NULL)
{
pointLink.push_back(currentTree);
removeAll(currentTree->left);
}
else if (currentTree->right != NULL) {
pointLink.push_back(currentTree);
removeAll(currentTree->right);
}
else {
// 如果删除的父节点是第一个
if (currentTree->data == node.data) {
haveHead = false;
}
else
delete currentTree;
if (pointLink.size() > 0) {
CSNode* tree = pointLink.back();
currentTree = tree; // 返回最后一个变量
currentTree->left = NULL;
pointLink.pop_back();
if (tree->right != NULL)
{
CSNode* crtList = tree->right;
tree->right = NULL;
removeAll(crtList);
}
removeAll(currentTree);
}
}/* */
}
//haveHead = false;
}
void DbTree::left(CSNode* currentTree)
{
cout << currentTree->data << endl;
if (currentTree->left != NULL)
{
left(currentTree->left);
}
if (currentTree->right != NULL) {
left(currentTree->right);
}
}
void DbTree::leftShow() {
if (haveHead)
left(&node);
}
/* 中序,左中右的检测,左边有值则将当前值加入对战,左边没有则将当前输出显示并查询右边,如果有则继续将其作为起始点同样的查询
* 上面结束后从堆栈中取出继续同样操作(但左边的不用再处理因为已经执行),直到堆栈为空
*/
void DbTree::center(CSNode* currentTree)
{
if (currentTree->left != NULL)
{
vct.push_back(*currentTree);
center(currentTree->left);
}
else {
//显示或输出当前的,并添加到返回链表
cout << currentTree->data << endl;
orderlyVct.push_back(*currentTree);
// 并对右边进行检测
if (currentTree->right != NULL) {
center(currentTree->right);
}
else // 负责对堆栈进行同样操作
{
if (vct.size() > 0) {
currentTree = &vct.back(); // 返回最后一个变量
vct.pop_back();
currentTree->left = NULL;
center(currentTree);
}
}
}
}
vector DbTree::centerShow()
{
orderlyVct.clear(); // 先清空再进去全部添加
if (haveHead)
center(&node);
return orderlyVct;
}
/* 输出顺序:左右中;
*/
void DbTree::right(CSNode* currentTree) {
if (currentTree->left != NULL)
{
vct.push_back(*currentTree);
right(currentTree->left);
}
else if (currentTree->right != NULL) {
vct.push_back(*currentTree);
right(currentTree->right);
}
else {
cout << currentTree->data << endl;
if (vct.size() > 0) {
CSNode* tree = &vct.back();
if (tree->right != NULL && tree->right->data == currentTree->data)
tree->right = NULL;
currentTree = tree; // 返回最后一个变量
vct.pop_back();
currentTree->left = NULL;
right(currentTree);
}
}
}
void DbTree::rightShow() {
if (haveHead)
right(&node);
}
// 将二叉树重新排序生成
void DbTree::balance()
{
vector thisVct;
thisVct = centerShow();
// 新建二叉树,每次已对应中间值添加
for (int i = 0; i < thisVct.size(); i++) {
}
}