二叉链表

 

二叉树数据元素类型为整型,以二叉链表为存储结构。试编程实现:

⑴ 生成一棵二叉树.

⑵ 用递归算法、非递归算法实现二叉树的遍历;

⑶ 求度分别为012的结点的数目,分别用递归算法、非递归算法实现;

⑷ 按层次遍历二叉树(提示:使用一个队列实现)

*⑸ 求二叉树的高度(深度)

*⑹ 判断是否为完全二叉树,输出"Yes!"/"No!"

*⑺ 交换每个结点的左右子树;

*⑻ 对交换左右子树后的二叉树作中序遍历。

* 求某结点的祖先集合。

显示二叉树

//所有头文件 #include<iostream> #include<stack> #include<queue> #include<stdlib.h> #include<stdio.h> using namespace std; //结点类 class BNode { public: int data; BNode *lchild,*rchild; BNode() { lchild=rchild=NULL; } BNode(int d,BNode *childl=NULL,BNode *childr=NULL) { data=d; lchild=childl; rchild=childr; } }; //二叉树类 class BTree { public: BNode *root; BTree() { root=NULL; } BNode *CreatTree();//先序生成一棵二叉树 void PreOrderTraverse(BNode *r);//递归先序遍历 void InOrderTraverse(BNode *r);//递归中序遍历 void PostOrderTraverse(BNode *r);//递归后序遍历 void Un_PreOrderTraverse(BNode *r);//非递归先序遍历 void Un_InOrderTraverse(BNode *r);//非递归中序遍历 void Un_PostOrderTraverse(BNode *r);//非递归后序遍历 void LevelOrderTraverse(BNode *r);//利用队列层次遍历二叉树 int TreeHeight(BNode *r);//求二叉树的高度(深度) int TreeNodeCount(BNode *r,int);//递归求0,1,2度的结点数 int Un_TreeNodeCount(BNode *r,int);//非递归求0,1,2度的结点数 int FullTree(BNode *r);//判断是否为完全二叉树 void SaveBtree(BNode *r);//采用文件形式保存数据,存入的数据为后序遍历的 BNode * Change(BNode *r);//交换每个结点的左右子树; void AncestorsNode(BNode *r,int d);// 求某结点的祖先集合 void PrintTree(BNode *r,int g);//按凹入表形式打印输出二叉树的元素,g表示结点所在层次,初次调用时g=0 }; //先序生成一棵二叉树 BNode *BTree::CreatTree() { BNode *p=NULL; char ch[10]; scanf("%s",ch); if(strcmp(ch,"0")==0)p=NULL;//input "x",p=NULL else { if(!(p=new BNode())) { cout<<"Error!"<<endl; exit(1); } p->data = atoi(ch);//string-->int p->lchild=CreatTree(); p->rchild=CreatTree(); } return p; } //递归先序遍历 void BTree::PreOrderTraverse(BNode *r) { if(r!=NULL) { cout<<r->data<<' '; PreOrderTraverse(r->lchild); PreOrderTraverse(r->rchild); } } //递归中序遍历 void BTree::InOrderTraverse(BNode *r) { if(r) { InOrderTraverse(r->lchild); cout<<r->data<<' '; InOrderTraverse(r->rchild); } } //递归后序遍历 void BTree::PostOrderTraverse(BNode *r) { if(r) { PostOrderTraverse(r->lchild); PostOrderTraverse(r->rchild); cout<<r->data<<' '; } } //采用文件形式保存数据,存入的数据为后序遍历的 void BTree::SaveBtree(BNode *r) { FILE *Save; stack<BNode *>TreeStack; //定义stack对象 if((Save=fopen("c://Btree.dat","wb"))!=NULL) { while(r||!TreeStack.empty()) //判断栈空和r { if(r) { TreeStack.push(r); //入栈 if(r)fprintf(Save,"%d", r->data);; r=r->lchild; } else { r=TreeStack.top(); //访问栈顶 TreeStack.pop(); //出栈,出栈操作只是删除栈顶元素,并不返回该元素 r=r->rchild; } } } else printf("File error!"); fclose(Save); } //非递归先序遍历 void BTree::Un_PreOrderTraverse(BNode *r) { stack<BNode *>TreeStack; //定义stack对象 while(r||!TreeStack.empty()) //判断栈空和r { if(r) { TreeStack.push(r); //入栈 if(r)cout<<r->data<<' '; r=r->lchild; } else { r=TreeStack.top(); //访问栈顶 TreeStack.pop(); //出栈,出栈操作只是删除栈顶元素,并不返回该元素 r=r->rchild; } } } //非递归中序遍历 void BTree::Un_InOrderTraverse(BNode *r) { stack<BNode *>TreeStack; //定义stack对象 while(r||!TreeStack.empty()) //判断栈空和r { if(r) { TreeStack.push(r); //入栈 r=r->lchild; } else { r=TreeStack.top(); //访问栈顶 TreeStack.pop(); //出栈,出栈操作只是删除栈顶元素,并不返回该元素 if(r)cout<<r->data<<' '; r=r->rchild; } } } //非递归后序遍历 void BTree::Un_PostOrderTraverse(BNode *r) { stack<BNode *>TreeStack; //定义stack对象 BNode *p; //引入一个标志 while(r||!TreeStack.empty()) //判断栈空和r { if(r) { TreeStack.push(r); //入栈 r=r->lchild; } else { r=TreeStack.top(); //访问栈顶 if(r->rchild&&r->rchild!=p) //使用p节点表示访问了右子树 { r=r->rchild; TreeStack.push(r); r=r->lchild; } else { TreeStack.pop(); //出栈,出栈操作只是删除栈顶元素,并不返回该元素 if(r)cout<<r->data<<' '; p=r; r=NULL; } } } } //利用队列层次遍历二叉树 void BTree::LevelOrderTraverse(BNode *r) { queue<BNode *>TreeQueue; //定义queue对象 if(r)TreeQueue.push(r); //入队列 while(!TreeQueue.empty()) //判断队列空 { r=TreeQueue.front(); //访问队列头 if (r->lchild) TreeQueue.push(r->lchild); if (r->rchild) TreeQueue.push(r->rchild); TreeQueue.pop(); //出队列,操作只是删除队列头元素,并不返回该元素 cout<<r->data<<' '; } } //递归求0,1,2度的结点数 int BTree::TreeNodeCount(BNode *r,int degree) { int d=0,num=0; if(r) { if(r->lchild) { d++; num+=TreeNodeCount(r->lchild,degree); } if(r->rchild) { d++; num+=TreeNodeCount(r->rchild,degree); } if(d==degree) num++; } return num; } //非递归求0,1,2度的结点数 int BTree::Un_TreeNodeCount(BNode *r,int degree) { int d=0,num=0; BNode *p=NULL; stack<BNode *>TreeStack; //定义stack对象 if(r) { TreeStack.push(r); while(!TreeStack.empty())//stack is empty,return 1;not empty,return 0 { d=0; p=TreeStack.top(); TreeStack.pop(); if(p->rchild) { TreeStack.push(p->rchild); d=1; } if(p->lchild) { TreeStack.push(p->lchild); d=2; } if(d==degree) num++; } } return num; } //求二叉树的高度(深度) int BTree::TreeHeight(BNode *r) { int treehight,lefthight,righthight; if(!r)treehight=0; else { lefthight=TreeHeight(r->lchild); righthight=TreeHeight(r->rchild); treehight=1+(lefthight>=righthight?lefthight:righthight); } return treehight; } //判断是否为完全二叉树 int BTree::FullTree(BNode *r) { BNode *p=NULL; queue<BNode *>TreeQueue; //定义queue对象 if(r)TreeQueue.push(r); //入队列 while((r=TreeQueue.front())!=NULL) //进行层次遍历,把NULL结点也放入,访问到第一个NULL结点结束 { TreeQueue.pop(); TreeQueue.push(r->lchild); TreeQueue.push(r->rchild); } while(!TreeQueue.empty())//判断NULL结点这一层是否有非NULL { p=TreeQueue.front(); if(p!=NULL)//如果有非NULL,说明非NULL前有NULL结点,则非完全二叉树 { return 0; } TreeQueue.pop(); } return 1; } //交换每个结点的左右子树; BNode * BTree::Change(BNode *r) { BNode *temp; if(r) { temp=r->lchild; r->lchild=r->rchild; r->rchild=temp; Change(r->lchild); Change(r->rchild); } return r; } // 求某结点的祖先集合 void BTree::AncestorsNode(BNode *r,int d) { stack<BNode *>TreeStack; //定义stack对象 BNode *p; //引入一个标志 //算法:采用后序非递归遍历 ,栈中该元素前的元素即为其祖先节点 while(r||!TreeStack.empty()) //判断栈空和r { if(r) { TreeStack.push(r); //入栈 r=r->lchild; } else { r=TreeStack.top(); //访问栈顶 if(r->rchild&&r->rchild!=p) //使用p节点表示访问了右子树 { r=r->rchild; TreeStack.push(r); r=r->lchild; } else { TreeStack.pop(); //出栈,出栈操作只是删除栈顶元素,并不返回该元素 if(r->data==d)break;//栈中剩下的即是r的祖先结点 p=r; r=NULL; } } } while(!TreeStack.empty()) //输出栈中结点 { r=TreeStack.top(); TreeStack.pop(); cout<<r->data<<' '; } } //按凹入表形式打印输出二叉树的元素,g表示结点所在层次,初次调用时g=0 void BTree::PrintTree(BNode *r,int g) { int j; if(!r) { cout<<"Error:No BTree!"<<endl; return; } if(r->lchild) PrintTree(r->lchild,g+1); //打印左子树 for(j=0;j<g;j++) printf(" "); //打印(g-1)*3个空格以表示出层次 printf("%d/n",r->data); //打印r元素,换行 if(r->rchild) PrintTree(r->rchild,g+1); //打印右子树 } int main() { BTree a; int d,k; printf(" /t/t/tBTree/n"); printf("********************************************************************************"); printf("1,Create BTree(PreOrder) 2,PrintTree/n"); printf("3,PreOrderTraverse 4,InOrderTraverse/n"); printf("5,PostOrderTraverse 6,Un_PreOrderTraverse/n"); printf("7,Un_InOrderTraverse 8,Un_PostOrderTraverse/n"); printf("9,LevelOrderTraverse 10,TreeHeight/n"); printf("11,TreeNodeCount(0,1 or 2) 12,Un_TreeNodeCount(0,1 or 2)/n"); printf("13,Change 14,AncestorsNode/n"); printf("15,FullTree 16,Save in /"c://Btree.dat/"/n"); printf("17,Exit/n"); printf("********************************************************************************"); while(1) { printf("Your option(end with Enter):"); scanf("%d",&k); switch(k) { case 1: printf("Input the data by pre order traverse to cteat a BTree(NULL instead by 'x'):/n"); a.root=a.CreatTree(); break; case 2: printf("Print:/n"); a.PrintTree(a.root,0); break; case 3: printf("PreOrderTraverse:"); a.PreOrderTraverse(a.root); printf("/n"); break; case 4: printf("InOrderTraverse:"); a.InOrderTraverse(a.root); printf("/n"); break; case 5: printf("PostOrderTraverse:"); a.PostOrderTraverse(a.root); printf("/n"); break; case 6: printf("Un_PreOrderTraverse:"); a.Un_PreOrderTraverse(a.root); printf("/n"); break; case 7: printf("Un_InOrderTraverse:"); a.Un_InOrderTraverse(a.root); printf("/n"); break; case 8: printf("Un_PostOrderTraverse:"); a.Un_PostOrderTraverse(a.root); printf("/n"); break; case 9: printf("LevelOrderTraverse:"); a.LevelOrderTraverse(a.root); printf("/n"); break; case 10: d=a.TreeHeight(a.root); printf("TreeHeight----%d/n",d); break; case 11: printf("TreeNodeCount:/n"); d=a.TreeNodeCount(a.root,0); printf("0 degree--->%d/n",d); d=a.TreeNodeCount(a.root,1); printf("1 degree--->%d/n",d); d=a.TreeNodeCount(a.root,2); printf("2 degree--->%d/n",d); break; case 12: printf("Un_TreeNodeCount:/n"); d=a.Un_TreeNodeCount(a.root,0); printf("0 degree--->%d/n",d); d=a.Un_TreeNodeCount(a.root,1); printf("1 degree--->%d/n",d); d=a.Un_TreeNodeCount(a.root,2); printf("2 degree--->%d/n",d); break; case 13: a.root=a.Change(a.root); printf("Change BTree successfully!/n"); break; case 14: printf("Input data of node:"); scanf("%d",&d); printf("Ancestors of Node:"); a.AncestorsNode(a.root,d); printf("/n"); break; case 15: d=a.FullTree(a.root); if(d==1)cout<<"Yes!"<<endl; else cout<<"No!"<<endl; break; case 16: a.SaveBtree(a.root); cout<<"Save the files successfully!"<<endl; break; case 17: exit(0); break; default: break; } } return 0; }  

 

转载于:https://www.cnblogs.com/louffy/archive/2011/06/08/9496736.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值