链式二叉树的递归与遍历
来源:互联网 发布:淘宝无线端装修工具 编辑:程序博客网 时间:2024/04/29 21:39
//测试数据:EBH GAC F D #include<iostream>#include<cstdio>#include<stack>#include<queue>using namespace std;typedef char Elemtype;//定义这棵树的结点typedef struct node{ Elemtype data; struct node *lchild; struct node *rchild;}BitTree;//递归先序遍历void PreOrder(BitTree *bt){ if(bt!=NULL) { cout<<bt->data; PreOrder(bt->lchild); PreOrder(bt->rchild); }}//非递归先序遍历void Preorder(BitTree *bt){ BitTree *p; stack<BitTree *> s; s.push(bt); while(!s.empty()) { p=s.top(); s.pop(); while(p) { cout<<p->data; if(p->rchild) s.push(p->rchild); p=p->lchild; } }}//递归中序遍历void InOrder(BitTree *bt){ if(bt!=NULL) { InOrder(bt->lchild); cout<<bt->data; InOrder(bt->rchild); }}//非递归中序遍历void Inorder(BitTree *bt){ stack<BitTree *> s; s.push(bt); BitTree *p; p=bt->lchild; while(p||!s.empty()) { while(p) { s.push(p); p=p->lchild; } p=s.top(); s.pop(); cout<<p->data; p=p->rchild; }}//递归后序遍历void PostOrder(BitTree *bt){ if(bt!=NULL) { PostOrder(bt->lchild); PostOrder(bt->rchild); cout<<bt->data; }}//非递归后序遍历void Postorder(BitTree *bt){ stack<BitTree *> s; BitTree *p,*q; p=bt; q=NULL; while(p||!s.empty())//使用p的原因是方便第一次进入,优化代码 { if(p!=q) { while(p) { s.push(p); if(p->lchild) p=p->lchild; else p=p->rchild; } } if(s.empty()) break;//写这句话的原因是访问根结点结束后,p为非空,所以还是能够进入循环,但堆栈已空,所以要用这句话推出 q=s.top(); if(q->rchild==p) { s.pop(); cout<<q->data; p=q; } else p=q->rchild; }}//二叉树的非递归层次遍历void levelBitTree(BitTree *bt){ queue<BitTree *> q; BitTree *p; p=NULL; p=bt; if(p) q.push(p); while(!q.empty()) { p=q.front(); q.pop(); cout<<p->data; if(p->lchild) q.push(p->lchild); if(p->rchild) q.push(p->rchild); }}//建立二叉链表算法BitTree *creBitTree(){ BitTree *bt; Elemtype x; scanf("%c",&x); if(x==' ') bt=NULL; else{ bt=(BitTree *)malloc(sizeof(BitTree)); bt->data=x; bt->lchild=creBitTree(); bt->rchild=creBitTree(); } return bt;}//统计二叉树中叶子节点的个数int cleaf=0;void countleaf(BitTree *bt){ if(bt!=NULL) { if(bt->lchild==NULL&&bt->rchild==NULL) cleaf++; countleaf(bt->lchild); countleaf(bt->rchild); }}//交换二叉树中所有结点的左右子树void exchange(BitTree *bt){ BitTree *t; if(bt!=NULL) { if(bt->lchild!=NULL||bt->rchild!=NULL) {t=bt->lchild;bt->lchild=bt->rchild;bt->rchild=t;} exchange(bt->lchild); exchange(bt->rchild); }}//求二叉树的高度int hightree(BitTree *bt){ int h,h1,h2; if(bt==NULL) h=0; else{ h1=hightree(bt->lchild); h2=hightree(bt->rchild); h=(h1>h2?h1:h2)+1; } return h;}//查找值为x的结点int ok=0;void searchtree(BitTree *bt,Elemtype x,BitTree **p1){ if(bt!=NULL&&!ok) { if(bt->data==x) {ok=1;*p1=bt;} else{ *p1=NULL; searchtree(bt->lchild,x,p1); searchtree(bt->rchild,x,p1); } }}//删除值为x的结点,使得其左右子树的安排仍然满足原来的中序遍历序列/*分析:为了保持中序遍历序列不变,对于找到的结点p可以分为4种情况考虑 (1)若结点p为叶子结点,则只需将该结点p的双亲结点f的左指针或右指针置为空即可 (2)若结点p的左子树为空,则只需将该结点p的双亲结点f的左指针或右指针指向该结点p的右孩子即可 (3)若结点p的左子树非空,则只需找到结点p的左子树中最右下的结点s(s的右指针必为空),将该结点s的左子树接到该结点s的双亲结点q上,再用该结点s中的数据替换p中的数据,最后删除该结点(s)即可 (4)若结点p为根结点bt且该结点左子树为空,则只需将根结点的指针bt移到结点p的右子树上即可 详细图解分析在 秦玉平 马靖善所编的数据结构(第三版) p129-129的例5.14*///为了此功能专门设计的查找函数,f记录双亲结点,p记录查找到的结点int Find=0;void search(BitTree *bt,Elemtype x,BitTree **p,BitTree **f){ if(bt!=NULL&&!Find) { if(bt->data==x) {Find=1;*p=bt;} else{ if(!Find){ *f=bt; search(bt->lchild,x,p,f); } if(!Find){ *f=bt; search(bt->rchild,x,p,f); } } }}//删除x的函数void deltree(BitTree **bt,Elemtype x){ BitTree *p,*f; BitTree *q,*s; p=f=NULL; search(*bt,x,&p,&f); if(p!=NULL) { if(p->lchild!=NULL) { q=p->lchild; s=q; while(s->rchild!=NULL){q=s;s=s->rchild;} if(q!=s) q->rchild=s->lchild; else p->lchild=q->lchild; p->data=s->data; free(s); } else{ if(f!=NULL){ if(p==f->lchild) f->lchild=p->rchild; else f->rchild=p->rchild; } else *bt=(*bt)->rchild; free(p); } } else cout<<"Not find this node"<<endl;}int main(){ BitTree *bt;// BitTree **p1;// Elemtype x;// Elemtype y;// int h; bt=creBitTree();//建树// PreOrder(bt);//递归先序// cout<<endl;// InOrder(bt);//递归中序// cout<<endl;// PostOrder(bt);//递归后序// cout<<endl;// countleaf(bt);//统计叶子结点个数// cout<<cleaf<<endl;// exchange(bt);// PreOrder(bt);//递归先序// cout<<endl;// InOrder(bt);//递归中序// cout<<endl;// PostOrder(bt);//递归后序// cout<<endl;// h=hightree(bt);//求树的高度// cout<<h<<endl;// cin>>x;// p1=(BitTree **)malloc(sizeof(BitTree));//给**p开辟空间// searchtree(bt,x,p1);//找到x,并把x的地址存放在p里面,注意,p放的是x的地址,而不是这个地址里的内容// cout<<(*p1)->data<<endl;//输出p指的内容,也就是找到的x// cin>>y;// deltree(&bt,y);// InOrder(bt);//递归中序// cout<<endl;// Preorder(bt);//非递归先序遍历// cout<<endl;// Inorder(bt);//非递归中序遍历// cout<<endl;// Postorder(bt);//非递归后序遍历// cout<<endl; levelBitTree(bt); cout<<endl; return 0;}
0 0
- 链式二叉树的递归与遍历
- 二叉树的链式结构的非递归遍历
- 二叉树的链式结构递归遍历实现
- 链式二叉树的遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的链式存储的递归和非递归遍历
- 二叉树的创建与遍历(递归)
- 二叉树的创建与递归遍历
- 二叉树的递归遍历与复制
- 链式二叉树的中序创建、递归中序遍历、非递归堆栈中序遍历、中序销毁
- 链式二叉树的后序创建、递归后序遍历、非递归堆栈后序遍历、后序销毁
- EasyUI扩展 datagrid列名包含特殊字符会导致表格错位(5)
- 建立一棵二叉树
- Android通过Servcie实现Notification定时发送
- 在无头单链表的一个非头节点前插入一个节点
- 通过包名和类名启动应用程序报错
- 链式二叉树的递归与遍历
- 机器学习相关资料推荐 http://blog.csdn.net/jiandanjinxin/article/details/51130271
- 前端页面常见js应用
- string.IsNullOrEmpty和string.IsNullOrWhiteSpace方法的区别
- 使用Unity3D 5.3.4 模仿2D游戏 FlappyBird(一)
- STL queue队列容器和priority_queue优先队列容器
- 每天laravel-20160727| Genaerator command-5
- java的编码原理
- java排序之快排