二叉树
1.存储结构
1.1顺序存储
注:容易造成空间浪费
1.2链表存储
typedef struct TreeNode *BinTree;
typedef BinTree Position;
struct TreeNode{
ElementType Date;
BinTree Left;
BinTree Right;
}
2.二叉树的遍历
2.1先序中序后序遍历
2.1.1先序遍历
2.1.2中序遍历
2.1.3后序遍历
2.2非递归遍历
- 遇到一个结点,就把它压栈,并去遍历它的左子树
- 左子树遍历结束后,从栈顶弹出结点并访问它
- 然后按其右指针再进行遍历
void InorderTraversal(BinTree BT)
{ BinTree T=BT;
Stack S=CreatStack(Maxsize);
while(T || !IsEmpty(S)){
while(T){
push(S,T);//一直向左并将沿途结点压入堆栈
T=T->Left;
}
if(!IsEmpty(S)){
T=Pop(S);//结点弹出堆栈
printf("%5d",T->Date);
T=T->Right;
}
}
}
2.3层序遍历
void LevelorderTraversal(BinTree BT)
{
Queue Q; BinTree T;
if(!BT) return;//若是空数则直接返回
Q = CreatQueue(MaxSize);//创建并初始化队列
AddQ(Q,BT);
while (!IsEmpty(Q)){
T = DeleteQ(Q);
print("%d\n",T->Date);//访问并取出队列的结点
if(T->Left) AddQ(Q,T->Left);
if(T->Right) AddQ(Q,T->Right);
}
}
return 0;
}
3.二叉搜索树
3.1二叉搜索数的查找
*代码实现
利用 “尾递归函数”
Position Find(ElementType X,BinTree BST)
{
if(!BST) return NULL;
else if(X>BST->Date)
return Find(X,BST->Right);//在右子树继续查找
else if(X<BST->Date)
return Find(X,BST->Left);
else
return BST;//查找成功,返回结点的地址
}
由于非递归函数执行效率高,故将 “尾递归函数” 改为 “迭代函数”
Position IterFind(ElementType X,BinTree BST)
{
while(BST){
if(X>BST->Date)
BST=BST->Right;
else if(X<BST->Date)
BST=BST->Left;
else return BST;
}
return NULL;//查找失败
}
查找效率取决于树的高度
3.2二叉树的插入
算法实现
BinTree Insert(ElementType X,BinTree BST)
{
if(!BST){ //若原树为空,则返回一个为结点的二叉搜索树
BST=malloc(sizeof(struct BinTree));
BST->Date=X;
BST->Left=BST->Right=NULL;
}else{
if(X<BST->Date)
BST->Left=Insert(X,BST->Left); //递归插入左子树
else if(X>BST->Date)
BST->Right=Insert(X,BST->Right);
}
return BST;
}
3.3二叉搜索树的删除
算法实现
BinTree Delete(ElementType X,BinTree BST)
{
Position Temp;
if(X>BST->Right)
BST->Right=Delete(X,BST->Right);
else if(X<BST->Left)
BST->Left=Delete(X,BST->Left);
else //找到要删除的结点
if(BST->Right && BST->Left){
Temp=FindMin(BST->Right);
BST->Date=Temp->Date;
BST->Right=Delete(Temp->Date,BST->Right);
}else{ //被删除结点有一个或者无子节点
Temp=BST;
if(!BST->Left)
BST=BST->Right;
else if(!BST->Right)
BST=BST->Left;
Free(Temp);
}
}
4.平衡二叉树
4.1什么是平衡二叉树
平衡因子(Balence Factor 简称BF):BF(T)=hL-hR,hL和hR分别代表左右字树高度。
平衡二叉树(AVL树)
空树或者任一结点左、右字树高度差的绝对值不超过1,即|BF(T)|<=1
4.2平衡二叉树的调整
4.2.1RR旋转(右单旋)/LL旋转
4.2.2LR旋转(左单旋)/RL旋转
5.判别是否是同一个搜索树
代码实现
#include<stdio.h>
#include<stdlib.h>
typedef struct TreeNode *Tree;
struct TreeNode{
int v;
Tree Left,Right;
int flag;
};
Tree MakeTree(int N);
Tree NewNode(int V);
Tree Insert(Tree T,int V);
int cheak(Tree,int V);
int Judge(Tree T,int N);
void ResetT(Tree T);
void FreeTree(Tree T);
int main()
{
int N,L,i;
Tree T;
scanf("%d",&N);
while(N)
{
scanf("%d",&L);
T=MakeTree(N);
for(i=0;i<L;i++)
{
if(Judge(T,N)) printf("Yes!");
else printf("No!");
ResetT(T);
}
FreeTree(T);
scanf("%d",&N);
}
return 0;
}
Tree MakeTree(int N) //建树
{
Tree T;
int i,V;
scanf("%d",&V);
NewNode(V);
for(i=1;i<N;i++)
{
scanf("%d",&V);
T=Insert(T,V);
}return T;
}
Tree NewNode(int V) //建立搜索树根
{
Tree T=(Tree)malloc(sizeof(struct TreeNode));
T->v=V;
T->Left=T->Right=NULL;
T->flag=0;
return T;
}
Tree Insert(Tree T,int V) //插入结点
{
if(!T) T=NewNode(V);
else{
if(V>T->v)
T->Right=Insert(T->Right,V);
else if(V<T->v)
T->Left=Insert(T->Left,V);
}
return T;
}
int cheak(Tree T,int V) // 检查结点顺序是否相同
{
if(T->flag){
if(V<T->v) return cheak(T->Left,V);
else if(V>T->v) return cheak(T->Right,V);
else return 0;
}
else{
if(V==T->v){
T->flag=1;
return 1;
}
else return 0;
}
}
int Judge(Tree T,int N){ //判断序列是否与T相同
int i,V,flag=0;
scanf("%d",&V);
if(V!=T->v) flag=1;
else T->flag=1;
for(i=1;i<N;i++){
scanf("%d",&V);
if((!flag)&& (!cheak(T,V))) flag=1;;
}
if(flag) return 0;
else return 1;
}
void ResetT(Tree T) //清楚T中各结点flag标记
{
if(T->Left) ResetT(T->Left);
if(T->Right) ResetT(T->Right);
T->flag=0;
}
void FreeTree(Tree T) //释放T空间
{
if(T->Left) FreeTree(T->Left);
if(T->Right) FreeTree(T->Right);
free(T);
}
参考文献:
【浙江大学数据结构 陈越】