程序设计代码 贴着玩。。六

数据结构二叉树类的实现

//类的头文件
#ifndef BINTREE_H_INCLUDED
#define BINTREE_H_INCLUDED
#include<iostream>
using namespace std;

class BinTreeNode{
private:
   BinTreeNode *left, *right;
   char c;
public:
   BinTreeNode();
   BinTreeNode(BinTreeNode* left, BinTreeNode* right, char ch);
   ~BinTreeNode();
   BinTreeNode* GetLeft()const;
   void SetLeft(BinTreeNode* t);
   BinTreeNode* GetRight()const;
   void SetRight(BinTreeNode* t);
   char GetC()const;
   void SetC(char c);
};

class BinTree{
private:
   BinTreeNode *root;
public:
   BinTree(BinTreeNode *t):root(t) {}
   virtual ~BinTree();///析构函数删除整棵树
   BinTreeNode* CreateBinTree(FILE *fp);
   ///在以t为根结点的子树中搜索结点p的父节点
   BinTreeNode* Father(BinTreeNode* t, BinTreeNode* p);
   ///在以结点t为根结点的子树中查找data域为item的结点
   BinTreeNode* Find(BinTreeNode* t, char ch);
   void del(BinTreeNode *t);
   void DelSubtree(BinTreeNode* t);///从树中删除结点t及其左右子树
   void PreOrder(const BinTreeNode* t)const;///先根遍历,非递归
   void InOrder(const BinTreeNode* t)const;///中根遍历,非递归版本的
   void PostOrder(const BinTreeNode* t)const;///后根遍历,递归版本的
   void LevelOrder(BinTreeNode* t)const;///层次遍历
   ///将node结点插入到t的子结点,flag为真时,插入到左子结点,flag为false时插入到右子结点
   void Insert(BinTreeNode* t, char ch, bool flag);
   BinTreeNode* GetRoot();
   void SetRoot(BinTreeNode* t);
   bool isEmpty();
};

#endif // BINTREE_H_INCLUDED


//类的定义文件
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stack>
#include<queue>
#include"BinTree.h"

using namespace std;

BinTreeNode::BinTreeNode() {}

BinTreeNode::BinTreeNode(BinTreeNode* l, BinTreeNode* r, char ch) {
   left = l;
   right = r;
   c = ch;
}

BinTreeNode::~BinTreeNode() {
}

char BinTreeNode::GetC()const {
   return c;
}

BinTreeNode* BinTreeNode::GetLeft()const {
   return left;
}

BinTreeNode* BinTreeNode::GetRight()const {
   return right;
}

void BinTreeNode::SetC(char ch) {
   c = ch;
}

void BinTreeNode::SetLeft(BinTreeNode* t){
   left = t;
}

void BinTreeNode::SetRight(BinTreeNode* t) {
   right = t;
}

BinTree::~BinTree() {
   this->DelSubtree(root);
}

BinTreeNode* BinTree::CreateBinTree(FILE *fp) {
   BinTreeNode* t;
   char data;
   fscanf(fp, "%c", &data);
   if(data == '^') {
      t = NULL;
      return t;
   } else {
      if(!(t = new BinTreeNode(NULL, NULL, data))) {
         return NULL;
      }
      t->SetLeft(CreateBinTree(fp));
      t->SetRight(CreateBinTree(fp));
      return t;
   }
}

BinTreeNode* BinTree::Father(BinTreeNode* t, BinTreeNode* p) {
   BinTreeNode* f = NULL;
   if(t == NULL || p == NULL) {
      return NULL;
   }
   if(p == root) {
      return NULL;
   }
   if(t->GetLeft() == p || t->GetRight() == p) {
      return t;
   } else {
      f = Father(t->GetLeft(), p);
      if(f != NULL) {
         return f;
      } else {
         return Father(t->GetRight(), p);
      }
   }
}

BinTreeNode* BinTree::Find(BinTreeNode* t, char ch) {
   BinTreeNode *node = NULL;
   if(t == NULL) {
      return NULL;
   }
   if( t->GetC() == ch) {
      return t;
   } else {

      node = Find(t->GetLeft(), ch);
      if(node != NULL) {
         return node;
      } else {
         return Find(t->GetRight(), ch);
      }
   }
}

void BinTree::del(BinTreeNode *t) {
   if(t != NULL) {
      del(t->GetLeft());
      del(t->GetRight());
      delete t;
   }
}

void BinTree::DelSubtree(BinTreeNode *t) {

   if(t == NULL) {
      return;
   }
   if(t == root) {
      del(t);
      root = NULL;
      return;
   }
   BinTreeNode *f, *p;
   p = t;
   f = Father(root, p);
   if(f) {
      if(f->GetLeft() == p) {
         f->SetLeft(NULL);
      }
      if(f->GetRight() == p) {
         f->SetRight(NULL);
      }
   }
   del(p);
}

void BinTree::PreOrder(const BinTreeNode* t) const {
   if(t == NULL) {
      return;
   }
   cout<<t->GetC();
   PreOrder(t->GetLeft());
   PreOrder(t->GetRight());

}

void BinTree::InOrder(const BinTreeNode* t) const {
   if(t == NULL) {
      return;
   }
   InOrder(t->GetLeft());
   cout<<t->GetC();
   InOrder(t->GetRight());
}

void BinTree::PostOrder(const BinTreeNode* t) const {
  // cout<<"hello"<<endl;
   if(t == NULL) {
      return;
   }
   PostOrder(t->GetLeft());
   PostOrder(t->GetRight());
   cout<<t->GetC();
}

void BinTree::LevelOrder(BinTreeNode* t) const {

   queue<BinTreeNode*>q;
   if(t != NULL) {
      q.push(t);
   }
   BinTreeNode *node;
   while(!q.empty()) {
      node = q.front();
      q.pop();
      cout << node->GetC();
      if(node->GetLeft() != NULL) {
         q.push(node->GetLeft());
      }
      if(node->GetRight() != NULL) {
         q.push(node->GetRight());
      }
   }
}

BinTreeNode* BinTree::GetRoot() {
   return root;
}

void BinTree::SetRoot(BinTreeNode* t) {
   root = t;
}

bool BinTree::isEmpty() {
   if(root == NULL) {
      return true;
   }
   return false;
}

void BinTree::Insert(BinTreeNode* t, char ch, bool flag) {
   BinTreeNode *r = Find(root, ch);
   if(r == NULL) {
      cout<<"未找到父节点t"<<endl;
      return;
   } else if(flag) {
      r->SetLeft(t);
      cout<<"插入成功"<<endl;
   } else {
      r->SetRight(t);
      cout<<"插入成功"<<endl;
   }
}



//用户界面

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include"BinTree.h"
using namespace std;

int main() {
   cout<<"开始创建二叉树"<<endl;
   cout<<"请按照输入所创建数的先根遍历的序列"<<endl;
   BinTreeNode *root;
   BinTree *tree = new BinTree(root);
   FILE *fp = fopen("tree.txt", "r");
   //char num[100];
   root = tree->CreateBinTree(fp);
  // fscanf(fp, "%s", num);
   fclose(fp);
   tree->SetRoot(root);
   cout<<"二叉树已经创建好"<<endl;
   cout<<tree->GetRoot()->GetC()<<endl;
   cout<<"请选择操作"<<endl;
   cout<<"0.退出\n1.查找值为item的结点\n2.查找结点p的父节点\n3.从树中删除结点t及其左右子树"<<endl;
   cout<<"4.先根遍历二叉树\n5.中根遍历二叉树\n6.后根遍历二叉树\n7.层次遍历二叉树\n8.判断树是否为空"<<endl;
   cout<<"9.向树中插入一个结点"<<endl;
   int choose;
   BinTreeNode *node, *temp;
   char ch;
   int side;
   cin>>choose;
   while(choose) {
      switch(choose) {
      case 1:
         cout<<"请输入所需要查找的结点的值";
         cin>>ch;
         node = tree->Find(tree->GetRoot(), ch);
         if(node != NULL) {
            cout<<"找到结点"<<endl;
         } else {
            cout<<"未找到结点"<<endl;
         }
         break;
      case 2:
         cout<<"查找结点p的父节点,请输入结点p的值"<<endl;
         cin>>ch;
         node = tree->Find(tree->GetRoot(), ch);
         temp = tree->Father(tree->GetRoot(), node);
         if(temp != NULL) {
            cout<<"值为"<<node->GetC()<<"的结点的父结点的值为"<<temp->GetC()<<endl;
         } else {
            cout<<"未找到p的父节点"<<endl;
         }
         break;
      case 3:
         cout<<"请输出要删除子树的根节点的值"<<endl;
         cin>>ch;
         node = tree->Find(tree->GetRoot(), ch);
         if(node != NULL) {
            cout<<"找到该结点,正在进行删除处理"<<endl;
            if(node == tree->GetRoot()) {
               cout<<"就是根节点"<<endl;
            }
            tree->DelSubtree(node);
         }
         break;
      case 4:
         cout<<"二叉树的先根遍历的序列为:";
         tree->PreOrder(tree->GetRoot());
         cout<<endl;
         break;
      case 5:
         cout<<"二叉树的中根遍历的序列为:";
         tree->InOrder(tree->GetRoot());
         cout<<endl;
         break;
      case 6:
         cout<<"二叉树的后根遍历的序列为:";
         tree->PostOrder(tree->GetRoot());
         cout<<endl;
         break;
      case 7:
         cout<<"二叉树的层次遍历的序列为:";
         tree->LevelOrder(tree->GetRoot());
         cout<<endl;
         break;
      case 8:
         if(tree->isEmpty()) {
            cout<<"树为空"<<endl;
         } else {
            cout<<"树非空"<<endl;
         }
         break;
      case 9:
         cout<<"请输入所要插入结点的值"<<endl;
         cin>>ch;
         temp = new BinTreeNode(NULL, NULL, ch);
         cout<<"请输入所要插入的结点的父节点的值"<<endl;
         cin>>ch;
         cout<<"请选择是插在左子树还是右子树,1表示左,0表示右"<<endl;
         cin>>side;
         tree->Insert(temp, ch, side);
      }
      cout<<"请选择操作"<<endl;
      cout<<"0.退出\n1.查找值为item的结点\n2.查找结点p的父节点\n3.从树中删除结点t及其左右子树"<<endl;
      cout<<"4.先根遍历二叉树\n5.中根遍历二叉树\n6.后根遍历二叉树\n7.层次遍历二叉树\n8.判断树是否为空"<<endl;
      cout<<"9.向树中插入一个结点"<<endl;
      cin>>choose;
   }
   return 0;
}


说明按照先根遍历序列输入一颗扩充二叉树,'^'是表示空节点的

测试数据

AB^C^D^^EF^^GH^IJ^^^^

对应的树为



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值