二叉树的顺序存储和基本操作
来源:互联网 发布:珀莱雅淘宝店真假 编辑:程序博客网 时间:2024/06/14 09:13
一、二叉树的定义:
二叉树是n个结点的有限集合,当n=0时称为空树,否则:(1)有且只有一个特殊的被称为树的根结点;(2)若n>1时,其余的结点被分为两个互不相交的子集,称为左右子树,并且左右子树都是二叉树;可以看出二叉树的定义是递归的。
二、二叉树的性质:
(1)在非空二叉树上,第i层至多有2^(i-1)个结点;
(2)深度为k的二叉树至多有2^k-1个结点;
(3)对任何一个二叉树,若其叶子结点数为n0,度为2的节点数为n2,则n0=n2+1;
满二叉树:一课深度为k且有2^k-1个结点的二叉树。
完全二叉树:如果深度为k,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1到n的结点一一对应,该二叉树称为完全二叉树。2^(k-1)<=n<=2^k-1
(4)n个结点的完全二叉树的深度k=[log2 n]+1,这里这个符号[x]表示小于等于x的整数;(证明过程,对上述n的不等式取对数)
(5)若对一棵有n个结点的完全二叉树(深度为└㏒2n┘+1)的结点按层(从第1层到第㏒2n +1层)序自左至右进行编号,则对于编号为i(1≦i≦n)的结点:
1 、若i=1:则结点i是二叉树的根,无双亲结点;否则,若i>1,则其双亲结点编号是[i/2]。
2、 如果2i>n:则结点i为叶子结点,无左孩子;否则,其左孩子结点编号是2i。
3、 如果2i+1>n:则结点i无右孩子;否则,其右孩子结点编号是2i+1。
三、二叉树的存储结构
1、顺序存储结构:
typedef char ElemType;typedef struct stree{ ElemType bitTree[MAX_SIZE]; int pointer; //number of points}STree;//initvoid STree_Init(STree &T){ for(int i=0;i<MAX_SIZE;++i) T.bitTree[i]='0'; T.pointer=0;}//insert rootint STree_insert_Root(STree &T,ElemType e){ T.bitTree[1]=e; T.pointer++; return 1;}//insert leftint STree_insert_Left(STree &T,int i,ElemType e){ if(i>=MAX_SIZE || i<0) { cout<<"argument is false!"<<endl; return -1; } T.bitTree[2*(i+1)]=e; T.pointer++; return 1;}//insert rightint STree_insert_Right(STree &T,int i,ElemType e){ if(i>=MAX_SIZE || i<0) { cout<<"argument is false!"<<endl; return -1; } T.bitTree[2*(i+1)+1]=e; T.pointer++; return 1;}//int STree_delete_Left(STree &T,int i,ElemType *x_left){ if(i>=MAX_SIZE || i<0) { cout<<"argument is false!"<<endl; return -1; } *x_left=T.bitTree[2*(i+1)]; T.pointer--; return 1;}//int STree_delete_Right(STree &T,int i,ElemType *x_right){ if(i>=MAX_SIZE || i<0) { cout<<"argument is false!"<<endl; return -1; } *x_right=T.bitTree[2*(i+1)+1]; T.pointer--; return 1;}int STree_delete_Root(STree &T,ElemType *x_root){ *x_root=T.bitTree[1]; T.pointer--; return 1;}//bool STree_empty(STree &T){ return T.pointer==0;}
2、三种遍历方式:前序、中序、后序
递归形式的遍历方式
//前序遍历void STree_Traver_1(STree &T,int i){ cout<<T.bitTree[i]<<" "; if(T.bitTree[2*i]!='0') STree_Traver_1(T,2*i); if(T.bitTree[2*i+1]!='0') STree_Traver_1(T,2*i+1);}//中序遍历void STree_Traver_2(STree &T,int i){ if(T.bitTree[2*i]!='0') STree_Traver_2(T,2*i); cout<<T.bitTree[i]<<" "; if(T.bitTree[2*i+1]!='0') STree_Traver_2(T,2*i+1);}//后序遍历void STree_Traver_3(STree &T,int i){ if(T.bitTree[2*i]!='0') STree_Traver_3(T,2*i); if(T.bitTree[2*i+1]!='0') STree_Traver_3(T,2*i+1); cout<<T.bitTree[i]<<" ";}
//前序遍历int STree_Traver_1_no(STree &T){ stack<int> s({'0'}); int p=1,q; if(STree_empty(T)) { cout<<"tree is empty!"<<endl; return -1; }do{ cout<<T.bitTree[p]<<" "; q=p*2+1; if(T.bitTree[q]!='0') s.push(q); p=p*2; if(T.bitTree[p]=='0') //到树的底部了,回退 { p=s.top(); s.pop(); } }while(T.bitTree[p]!='0'); return 1;}//中序遍历int STree_Traver_2_no(STree &T){ stack<int> s; int p=1; int b=1; /* if(STree_empty(T)) { cout<<"tree is empty!"<<endl; return -1; } */ do { while(T.bitTree[p]!='0') { s.push(p); p=p*2; } if(s.empty()) b=0; else { p=s.top(); s.pop(); cout<<T.bitTree[p]<<" "; p=p*2+1; } }while(b!=0); return 1;}//后序遍历int STree_Traver_3_no(STree &T){ int p=1; int b=1,top=0; int s1[20],s2[20]; do { while(T.bitTree[p]!='0') { s1[++top]=p; s2[top]=0; p=p*2; } if(top==0) b=0; else if(s2[top]==0) { p=s1[top]*2+1; s2[top]=1; } else { p=s1[top]; top--; cout<<T.bitTree[p]<<" "; T.bitTree[p]='0'; } }while(b!=0); return 1;}
阅读全文
0 0
- 二叉树的顺序存储和基本操作
- 顺序存储完全二叉树的基本操作
- 二叉树的顺序存储与基本操作
- 二叉树的链式存储和基本操作
- 二叉树的顺序存储和链式存储
- 二叉树的顺序存储和链式存储
- 关于二叉树的顺序存储和链式存储
- 二叉树的顺序存储
- 二叉树的顺序存储
- 二叉树的顺序存储
- 二叉树的顺序存储
- 二叉树的顺序存储
- 二叉树的顺序存储
- 二叉树的顺序存储
- 二叉树的顺序存储
- 链表,顺序表,链队,链栈,顺序队,顺序栈,二叉树的基本操作函数
- 队列的顺序存储的基本操作.....
- 队列的顺序存储的基本操作.....
- Eclipse进行远程调试linux 环境的tomcat配置
- HttpClient通过post上传文件和提交参数
- Linux内核编译安装
- java设计模式之代理模式(静态代理)
- 清除编译的内核源码文件
- 二叉树的顺序存储和基本操作
- tack笔记
- 在O(1)时间删除链表结点
- Spring Boot 整合 log4j2 实现日志管理
- Pahom on Water HDU
- ASM空间扩容
- Spring事务管理
- 后缀表达式的运算求值
- 浅谈HTTP中Get与Post的区别