上机作业之树:递归算法在二叉树中的简单应用
2016-11-10 10:22
246 查看
二叉树习题 3.5
设一棵二叉树以二叉链表表示,试编写有关二叉树的递归算法:1) 统计二叉树中度为1的结点个数;
2) 统计二叉树中度为2的结点个数;
3) 统计二叉树中度为0(叶节点)的结点个数;
4) 统计二叉树的高度;
5) 统计二叉树的宽度,即在二叉树的各层上具有结点数最多的那一层上结点总数;
6) 计算二叉树中各结点中最大元素的值;
7) 交换每个结点的左孩子结点和右孩子结点;
8) 从二叉树中删去所有叶节点;
编写算法判别给定二叉树是否为完全二叉树。
// // main.cpp // 3.5 // // Created by Cyril on 2016/11/9. // Copyright © 2016年 Cyril. All rights reserved. // #include <iostream> #include <queue> #define MIN -100000000 using namespace std; //二叉树结点的定义 template <class T> class BT; template <class T> class BTNode { friend class BT<T>; private: T data; BTNode *lChild; BTNode *rChild; public: BTNode(); BTNode(T& d);//给定数据域的值得构造函数 BTNode(T& d, BTNode *l, BTNode *r);//给定数据域以及左右孩子的构造函数 BTNode<T> *GetLChild();//返回左孩子结点的指针 BTNode<T> *GetRChild();//返回右孩子结点的指针 void SetLChild(BTNode<T> *l);//设置左孩子结点 void SetRChild(BTNode<T> *r);//设置右孩子结点 ~BTNode(){} T GetValue();//返回该节点数据值 bool SetValue(T& val);//设置该点数据值 bool IsLeaf();//判断是否为叶子结点 void DisplayNode();//输出结点 }; template <class T> BTNode<T>::BTNode() { lChild=rChild=NULL; } template <class T> BTNode<T>::BTNode(T& d)//给定数据域的值得构造函数 { lChild=rChild=NULL; data=d; } template <class T> BTNode<T>::BTNode(T& d, BTNode *l, BTNode *r)//给定数据域以及左右孩子的构造函数 { lChild=l; rChild=r; data=d; } template <class T> BTNode<T>* BTNode<T>:: GetLChild()//返回左孩子结点的指针 { return lChild; } template <class T> BTNode<T>* BTNode<T>:: GetRChild()//返回右孩子结点的指针 { return rChild; } template <class T> void BTNode<T>:: SetLChild(BTNode<T> *l)//设置左孩子结点 { lChild=l; } template <class T> void BTNode<T>:: SetRChild(BTNode<T> *r)//设置右孩子结点 { rChild=r; } template <class T> T BTNode<T>:: GetValue()//返回该节点数据值 { return data; } template <class T> bool BTNode<T>:: SetValue(T& val)//设置该点数据值 { this->data=val; return true; } template <class T> bool BTNode<T>:: IsLeaf()//判断是否为叶子结点 { if(lChild==NULL&&rChild==NULL) return true; else return false; } template <class T> void BTNode<T>:: DisplayNode()//输出结点 { cout<<"该结点的数据为: "<<data<<endl; } //二叉树类的定义 template <class T> class BT { private: BTNode<T> *root;//二叉树的根节点 int s;//用于记录结点的个数 public: BT(){root=NULL;} ~BT(){} void NewTree();//创建新树 BTNode<T>* SetSubTree();//创建子树并返回子树的根结点地址 bool IsEmpty();//判断是否为空树 BTNode<T>* GetRoot();//返回根节点 bool GetParent(BTNode<T> *cur);//返回当前结点的父节点.(未实现) bool GetLSibling(BTNode<T> *cur);//返回当前结点的左兄弟.(未实现) bool GetRSibling(BTNode<T> *cur);//返回当前结点的右兄弟.(未实现) bool LevelOrder(BTNode<T> *r);//广度优先遍历 bool PreOrder(BTNode<T> *r);//前序遍历 bool DeleteNode(BTNode<T> *r);//删除以r为根结点的子树.(未实现) void Display();//输出树 void RecDisplay(BTNode<T> *t);//用于输出树时的循环迭代 int GetDegree(int num);//计算二叉树中度为num的结点个数,并返回 int CalDegree2(BTNode<T> *r);//计算结点为2的结点个数,并返回 int CalDegree1(BTNode<T> *r);//计算结点为1的结点个数,并返回 int CalDegree0(BTNode<T> *r);//计算结点为0的结点个数,并返回 int GetHeight(BTNode<T> *r);//计算二叉树的高度,并返回 void CalWidth(BTNode<T> *r,int *count,int depth);//递归计算二叉树的宽度 int GetWidth();//计算二叉树宽度 T GetMax(BTNode<T> *r);//计算二叉树中结点的最大元素,并返回 void SwapChildren(BTNode<T> *r);//交换每一个结点的左孩子结点和右孩子结点 void DeleteLeaf(BTNode<T> *r);//删除叶节点 bool IsCompleteBT();//判断是否为完全二叉树 }; template <class T> void BT<T>::NewTree()//创建新树 { cout<<"请输入根结点的数据:"<<endl; root=SetSubTree(); } template <class T> BTNode<T>* BT<T>::GetRoot()//返回根节点 { return root; } template <class T> BTNode<T>* BT<T>:: SetSubTree()//创建子树并返回子树的根结点地址 { T t; cin>>t; BTNode<T> *p; if(t=='#') return NULL;//返回空指针 else { p=new BTNode<T>; p->SetValue(t); //cout<<"成功读入"<<t<<endl; cout<<"请输入左孩子结点的数据:(输入‘#’则表示不存在左孩子结点)"<<endl; p->SetLChild(SetSubTree()); cout<<"请输入右孩子结点的数据:(输入‘#’则表示不存在右孩子结点)"<<endl; p->SetRChild(SetSubTree()); return p; } } template <class T> bool BT<T>:: IsEmpty()//判断是否为空树 { return !root; } template <class T> bool BT<T>:: LevelOrder(BTNode<T> *r)//广度优先遍历 { queue<BTNode<T>*> NodeQueue; BTNode<T> *p=root; if(p) NodeQueue.push(p); while (!NodeQueue.empty()) { p=NodeQueue.front(); //...访问p指针指向的结点 //样例操作:广度优先输出树 cout<<p->data<<' '; NodeQueue.pop(); if(p->lChild) NodeQueue.push(p->lChild); if(p->rChild) NodeQueue.push(p->rChild); } return true; } template <class T> bool BT<T>:: PreOrder(BTNode<T> *r)//前序遍历 { if(r) { //...访问r指针指向的结点 //样例操作:深度优先输出树 cout<<r->data<<' '; PreOrder(r->lChild); PreOrder(r->rChild); return true; } return false; } template <class T> void BT<T>:: Display() { RecDisplay(root); cout<<endl; } template <class T> void BT<T>:: RecDisplay(BTNode<T> *t) { if(t!=NULL) { cout<<t->data; if(t->lChild||t->rChild) { cout<<'('; RecDisplay(t->lChild); cout<<','; if(t->rChild) RecDisplay(t->rChild); else cout<<'#'; cout<<')'; } } else { cout<<'#'; } } template <class T> int BT<T>:: GetDegree(int num)//计算二叉树中度为num的结点个数,并返回 { s=0; if(num==2) return CalDegree2(root); else if(num==1) return CalDegree1(root); else if(num==0) return CalDegree0(root); else return -1;//不合法就返回-1 } template <class T> int BT<T>:: CalDegree2(BTNode<T> *r)//计算结点为2的结点个数,并返回 { if(!r) return 0;//空指针返回0 s=(r->lChild!=NULL)&&(r->rChild!=NULL); return s+CalDegree2(r->lChild)+CalDegree2(r->rChild); } template <class T> int BT<T>:: CalDegree1(BTNode<T> *r)//计算结点为1的结点个数,并返回 { if(!r) return 0;//空指针返回0 s=(r->lChild!=NULL&&r->rChild==NULL)||(r->lChild==NULL&&r->rChild!=NULL);//异或算法 return s+CalDegree1(r->lChild)+CalDegree1(r->rChild); } template <class T> int BT<T>:: CalDegree0(BTNode<T> *r)//计算结点为0的结点个数,并返回 { if(r==NULL) return 0;//空指针返回1 s=(r->lChild==NULL)&&(r->rChild==NULL); return s+CalDegree0(r->lChild)+CalDegree0(r->rChild); } template <class T> int BT<T>:: GetHeight(BTNode<T> *r)//计算二叉树的高度,并返回 { if(!r) return 0; int left=GetHeight(r->lChild)+1; int right=GetHeight(r->rChild)+1; return (left>right)?left:right; } template <class T> void BT<T>:: CalWidth(BTNode<T> *r,int *count,int depth)//递归计算二叉树的宽度 { if(!r) return ; count[depth]++; CalWidth(r->lChild,count,depth+1); CalWidth(r->rChild,count,depth+1); } template <class T> int BT<T>:: GetWidth() { int de=GetHeight(root); int *count=new int [de]; for(int i=0;i<de;i++) count[i]=0; CalWidth(root,count,0); int max=0; for(int i=0;i<de;i++) max=((count[i]>max)?count[i]:max); return max; } template <class T> T BT<T>:: GetMax(BTNode<T> *r)//计算二叉树中结点的最大元素,并返回 { // cout<<r<<endl; if(r) { T left=GetMax(r->lChild); T current=r->data; T right=GetMax(r->rChild); T max=((left>right)?left:right); return ((current>max)?current:max); } else return MIN; } template <class T> void BT<T>::SwapChildren(BTNode<T> *r)//交换每一个结点的左孩子结点和右孩子结点 { if(!r) return; BTNode<T> *temp; temp=r->lChild; r->lChild=r->rChild; r->rChild=temp; SwapChildren(r->lChild); SwapChildren(r->rChild); } template <class T> void BT<T>:: DeleteLeaf(BTNode<T> *r)//删除叶节点 { if(!r) return; if(!root->lChild&&!root->rChild) { delete root; root=NULL; } if(r->lChild) { if(!r->lChild->lChild&&!r->lChild->rChild) { delete r->lChild; r->lChild=NULL; } else DeleteLeaf(r->lChild); } if(r->rChild) { if(!r->rChild->lChild&&!r->rChild->rChild) { delete r->rChild; r->rChild=NULL; } else DeleteLeaf(r->rChild); } } template <class T> bool BT<T>:: IsCompleteBT()//判断是否为完全二叉树 { queue<BTNode<T>*> NodeQueue; int flag=1; NodeQueue.push(root); while(!NodeQueue.empty()) { BTNode<T> *p=NodeQueue.front(); NodeQueue.pop(); if(p) { if(!flag) return false; NodeQueue.push(p->lChild); NodeQueue.push(p->rChild); } else { flag=0; } } return true; } int main() { BT<char> Tree; Tree.NewTree(); cout<<"该二叉树为"<<endl; Tree.Display(); if(Tree.IsCompleteBT()) cout<<"该二叉树为完全二叉树"<<endl; else cout<<"该二叉树不是完全二叉树"<<endl; for(int i=0;i<3;i++) { cout<<"二叉树中度为"<<i<<"的结点个数为:"<<Tree.GetDegree(i)<<endl; } cout<<"二叉树的高度为:"<<Tree.GetHeight(Tree.GetRoot())<<endl; cout<<"二叉树的宽度为:"<<Tree.GetWidth()<<endl; cout<<"二叉树的最大元素为:"<<Tree.GetMax(Tree.GetRoot())<<endl; cout<<"交换每一个左右孩子后的二叉树为:"<<endl; Tree.SwapChildren(Tree.GetRoot()); Tree.Display(); cout<<"删除叶节点后的二叉树为:"<<endl; Tree.DeleteLeaf(Tree.GetRoot()); Tree.Display(); return 0; }
相关文章推荐
- C++ 十一周上机作业-之-编程2(虚基类的简单使用) 东南大学 仪器科学与工程学院
- SDUT 1291数据结构上机测试4.1:二叉树的遍历与应用1
- 1291 数据结构上机测试4.1:二叉树的遍历与应用1
- 数据结构上机测试4.1:二叉树的遍历与应用1
- 二叉树及其应用-二叉树的遍历及哈夫曼树-数据结构上机实验
- 二叉树中递归算法的两个应用——数(非)叶子结点的数目和判断是否是排序二叉树
- 【数据结构】二叉树的简单操作及简单应用
- 【1291】数据结构上机测试4.1:二叉树的遍历与应用1 SDUTOJ
- 数据结构上机测试4.1:二叉树的遍历与应用1
- Servlet监听器与Timer定时器配合实现JAVA WEB应用简单自动作业
- 递归算法详解以及在二叉树中的应用
- Binary Tree Traversals(HDU1710)二叉树的简单应用
- 数据结构上机测试4.1:二叉树的遍历与应用
- 【1291】数据结构上机测试4.1:二叉树的遍历与应用1 SDUTOJ
- 数据结构上机测试4.1:二叉树的遍历与应用1
- 数据结构-------树与二叉树的几个简单应用
- 【数据结构上机练习】7. 二叉树的简单操作(2)
- 1489 求二叉树的先序遍历 1291 数据结构上机测试4.1:二叉树的遍历与应用1【二叉树遍历顺序转换】
- 二叉树的创建及其简单应用
- 数据结构上机测试4.1:二叉树的遍历与应用1