数据结构二叉树

二叉树

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);
}

参考文献:
【浙江大学数据结构 陈越】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值