/*---------------------------------------------------------------- // 文件名:D-forest.cpp // 文件功能描述:实现D森林,合并两棵树、查找结点深度、输出树、 // 创建标识:2010-2-20 zhangliqiang // 修改标识: // 修改描述: //----------------------------------------------------------------*/ #include "stdafx.h" #include "iostream" using namespace std; //构造树结点 struct TreeNode{ int name; //结点名称 int count; //包含结点数 int father; //父结点 int weight; //结点weight }; //初始化结点 void InitTree(TreeNode node[],int n) { for(int i=0;i<n;i++) { node[i].count=1; node[i].name=i; node[i].father=i; node[i].weight=0; } } //递归程序实现路径压缩 int Find(TreeNode p[],int i,int &w) { if(i!=p[i].father) { int faNewWeight; p[i].father=Find(p, p[i].father, faNewWeight); p[i].weight=p[i].weight+faNewWeight; w=p[i].weight; } else w=0; return p[i].father; } //计算树深度 int Find_Depth(int TreeNodeIndex,TreeNode p[],int n) { //结点不存在的情况 if(TreeNodeIndex<0||TreeNodeIndex>=n) { cout<<"该结点不存在"<<endl; return -1; } else if(TreeNodeIndex == p[TreeNodeIndex].father) { return p[TreeNodeIndex].weight; } else { int w; int rootIndex = Find(p,TreeNodeIndex,w); p[TreeNodeIndex].father = rootIndex; return (p[TreeNodeIndex].weight + p[rootIndex].weight); } } //合并两棵树 bool Link(int v,int r,TreeNode p[],int n) { int w; int root_v=Find(p,v,w);//返回v的根节点 int root_r=Find(p,r,w);//返回r的根节点 int vDepth = Find_Depth(v,p,n);//返回v的深度 int rDepth = Find_Depth(r,p,n);//返回r的深度 if(root_r==root_v) { cout<<"两个结点属于同一棵树,不能合并!"; return false; } else if(p[root_r].count<=p[root_v].count) { p[root_r].weight = vDepth + 1 - p[root_v].weight + p[root_r].weight; p[root_v].count = p[root_v].count + p[root_r].count; p[root_r].father = root_v; } else { p[root_r].weight = vDepth + 1 + p[root_r].weight; p[root_v].weight = p[root_v].weight - p[root_r].weight; p[root_r].count = p[root_v].count + p[root_r].count; p[root_v].father = root_r; } return true; } //输出D森林结果 void DisplayResult(TreeNode str[],int n) { for(int i=0;i<n;i++) { cout<<"结点名称:"<<str[i].name<<" 结点weight:"<<str[i].weight<<" 父节点:"<<str[i].father<<" 包含结点数:"<<str[i].count<<endl; } } //主程序开始 int main() { //用于存储结点个数 int nodeCount; cout<<"作业二 实现D森林"<<endl; cout<<"输入结点个数:"; cin>>nodeCount; TreeNode *mytree=new TreeNode[nodeCount]; InitTree(mytree,nodeCount); cout<<"初始化完成!结点名称分别为0~"<<nodeCount-1<<endl; int operationType; cout<<"您可执行的操作如下:"<<endl; cout<<"合并两棵树(代号1)"<<endl; cout<<"查找结点深度(代号2)"<<endl; cout<<"输出该树(代号3)"<<endl; cout<<"退出程序(代号0)"<<endl; cout<<"请输入操作类型代号(0,1,2,3):"; //获取操作代号,并执行对应的操作 while(cin>>operationType) { if(operationType==1) { int r,v; cout<<"分别输入包含的结点:"; while(cin>>r>>v) { if(r>=0&&r<nodeCount && v>=0&&v<nodeCount) { if(Link(v,r,mytree,nodeCount)) cout<<"合并成功!"<<endl; break; } else { cout<<"输入错误,请重新输入!"<<endl; } } } else if(operationType==2) { int TreeNodepoint; cout<<"请输入要查找的结点:"; while(cin>>TreeNodepoint) { if(TreeNodepoint<0||TreeNodepoint>=nodeCount) { cout<<"输入结点不存在!请重新输入!"<<endl; continue; } else { cout<<"该结点深度为:"<<Find_Depth(TreeNodepoint,mytree,nodeCount)<<endl; break; } } } else if(operationType==3) { cout<<"该树的数组内容为:"<<endl; DisplayResult(mytree,nodeCount); } else if(operationType==0) { break; } else { cout<<"输入操作数错误!请重新输入!"<<endl; } cout<<"请输入操作类型代号(0,1,2,3):"; } return 0; }