树与二叉树的常用操作函数总结

这里也常常用到一些栈与队列的操作函数,就不一一写了,栈与队列总结里会有这些操作;;

 

 

#include <stdio.h>
#include <stdlib.h>


/*二叉树的链式结构*/
typedef int ElementType;
typedef struct TNode *Position;
typedef Position BinTree;  /* 二叉树类型 */
struct TNode              /* 树结点定义 */
{
    ElementType Data;   /* 结点数据 */
    BinTree Left;      /* 指向左子树 */
    BinTree Right;    /* 指向右子树 */
} *BT;

//typedef struct SNode *BinTree;
//struct SNode
//{
//    int Data;
//    BinTree Left, Right;
//} *BT ;



/*二叉树四种遍历*/
void PreorderTraversal( BinTree BT )       //先序遍历
{
    if( BT )
    {
        printf("%d ", BT->Data );
        PreorderTraversal( BT->Left );
        PreorderTraversal( BT->Right );
    }
}

void InorderTraversal( BinTree BT )        //中序遍历
{
    if( BT )
    {
        InorderTraversal( BT->Left );      /* 此处假设对BT结点的访问就是打印数据 */
        printf("%d ", BT->Data);          /* 假设数据为整型 */
        InorderTraversal( BT->Right );
    }
}

void PostorderTraversal( BinTree BT )      //后序遍历
{
    if( BT )
    {
        PostorderTraversal( BT->Left );
        PostorderTraversal( BT->Right );
        printf("%d ", BT->Data);
    }
}

void LevelorderTraversal ( BinTree BT )    //层序遍历
{
    Queue Q;
    BinTree T;
    if ( !BT ) return;  /* 若是空树则直接返回 */
    Q = CreatQueue();  /* 创建空队列Q */
    AddQ( Q, BT );
    while ( !IsEmpty(Q) )
    {
        T = DeleteQ( Q );
        printf("%d ", T->Data); /* 访问取出队列的结点 */
        if ( T->Left )   AddQ( Q, T->Left );
        if ( T->Right )  AddQ( Q, T->Right );
    }
}





/*二叉搜索树操作*/

typedef int ElementType;
typedef struct TNode *Position;
typedef Position BinTree;  /* 二叉树类型 */
struct TNode               /* 树结点定义 */
{
    ElementType Data;      /* 结点数据   */
    BinTree Left;          /* 指向左子树 */
    BinTree Right;         /* 指向右子树 */
} *BT;



Position Find( ElementType x, BinTree T )
{
    if( T = NULL )
        return NULL;
    if( X < T->Data )
        return Find( X, T->Left );
    else
    if( X > T->Data )
        return Find( X, T->Right);
    else 
        return T;
}

Position FindMin ( BinTree T ) /*递归 */
{
    if( T == NULL )
        return NULL;
    else
    if( T->Left == NULL )
        return T;
    else
        return FindMin( T->Left );
}
Position FindMax( BinTree T ) /*非递归*/
{
    if( T!= NULL )
        while( T->Right != NULL )
            T = T->Right;
    return T;
}

BinTree Insert( BinTree BST, ElementType X )        //二叉搜索树的插入(建立)
{
    if( !BST )
    {
        /* 若原树为空,生成并返回一个结点的二叉搜索树 */
        BST = (BinTree)malloc(sizeof(struct TNode));
        BST->Data = X;
        BST->Left = BST->Right = NULL;
    }
    else
    {
        /* 开始找要插入元素的位置 */
        if( X < BST->Data )
            BST->Left = Insert( BST->Left, X );   /*递归插入左子树*/
        else  if( X > BST->Data )
            BST->Right = Insert( BST->Right, X ); /*递归插入右子树*/
        /* else X已经存在,什么都不做 */
    }
    return BST;
}
 
BinTree Delete( BinTree BST, ElementType X )       //二叉搜索树的删除
{
    Position Tmp;
    if( !BST )
        printf("要删除的元素未找到");
    else
    {
        if( X < BST->Data )
            BST->Left = Delete( BST->Left, X );     /* 从左子树递归删除 */
        else if( X > BST->Data )
            BST->Right = Delete( BST->Right, X ); /* 从右子树递归删除 */
        else
        {
            /* BST就是要删除的结点 */
            if( BST->Left && BST->Right )
            {
                /* 如果被删除结点有左右两个子结点 */
                Tmp = FindMin( BST->Right );            /* 从右子树中找最小的元素填充删除结点 */
                BST->Data = Tmp->Data;                 /* 从右子树中删除最小元素 */
                BST->Right = Delete( BST->Right, BST->Data );
            }
            else
            {
                /* 被删除结点有一个或无子结点 */
                Tmp = BST;
                if( !BST->Left )       /* 只有右孩子或无子结点 */
                    BST = BST->Right;
                else                   /* 只有左孩子 */
                    BST = BST->Left;
                free( Tmp );
            }
        }
    }
    return BST;
}







/*AVL树的旋转与插入*/
typedef struct AVLNode *Position;
typedef Position AVLTree; /* AVL树类型  */
struct AVLNode
{
    ElementType Data;     /* 结点数据   */
    AVLTree Left;         /* 指向左子树 */
    AVLTree Right;        /* 指向右子树 */
    int Height;           /* 树高       */
};
int GetHeight( Position p )
{
    if( p == NULL )
        return -1;
    else
        return p->Height;
}
#define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
AVLTree SingleLeftRotation ( AVLTree A )  //左单旋
{
    /* 注意:A必须有一个左子结点B */
    /* 将A与B做左单旋,更新A与B的高度,返回新的根结点B */
    AVLTree B = A->Left;
    A->Left = B->Right;
    B->Right = A;
    A->Height = MAX( GetHeight(A->Left), GetHeight(A->Right) ) + 1;
    B->Height = MAX( GetHeight(B->Left), A->Height ) + 1;
    return B;
}
AVLTree SingleRightRotation ( AVLTree A )
{
    AVLTree B = A->Right;
    A->Right = B->Left;
    B->Left = A;
    A->Height = MAX( GetHeight(A->Left), GetHeight(A->Right) ) + 1;
    B->Height = MAX( GetHeight(B->Right), A->Height) + 1;
    return B;
}

AVLTree DoubleLeftRightRotation ( AVLTree A )  //左-右双旋
{
    /* 注意:A必须有一个左子结点B,且B必须有一个右子结点C */
    /* 将A、B与C做两次单旋,返回新的根结点C */
    /* 将B与C做右单旋,C被返回 */
    A->Left = SingleRightRotation(A->Left);
    /* 将A与C做左单旋,C被返回 */
    return SingleLeftRotation(A);
}
AVLTree DoubleRightLeftRotation ( AVLTree A )
{
    A->Right = SingleLeftRotation(A);
    return SingleRightRotation(A);
}


AVLTree Insert( AVLTree T, ElementType X )
{
    /* 将X插入AVL树T中,并且返回调整后的AVL树 */
    if ( !T )
    {
        /* 若插入空树,则新建包含一个结点的树 */
        T = (AVLTree) malloc (sizeof(struct AVLNode));
        T->Data = X;
        T->Height = 0;
        T->Left = T->Right = NULL;
    }   /* if (插入空树) 结束 */
    else if ( X < T->Data )
    {
        /* 插入T的左子树 */
        T->Left = Insert( T->Left, X);
        if ( GetHeight(T->Left)-GetHeight(T->Right) == 2 )/* 如果需要左旋 */
        {
            if ( X < T->Left->Data )
                T = SingleLeftRotation(T);        /* 左单旋 */
            else
                T = DoubleLeftRightRotation(T);/* 左-右双旋 */
        }
    } /* else if (插入左子树) 结束 */
    else if ( X > T->Data )
    {
        /* 插入T的右子树 */
        T->Right = Insert( T->Right, X );
        if ( GetHeight(T->Left)-GetHeight(T->Right) == -2 ) /* 如果需要右旋 */
        {
            if ( X > T->Right->Data )
                T = SingleRightRotation(T);       /* 右单旋 */
            else
                T = DoubleRightLeftRotation(T); /* 右-左双旋 */
        }

    } /* else if (插入右子树) 结束 */

    /* else X == T->Data,无须插入 */
    T->Height = MAX( GetHeight(T->Left), GetHeight(T->Right) ) + 1;/* 别忘了更新树高 */
    return T;
}



/*堆的定义与操作*/
typedef struct HNode *Heap; /* 堆的类型定义 */
struct HNode
{
    ElementType *Data;    /* 存储元素的数组 */
    int Size;            /* 堆中当前元素个数 */
    int Capacity;       /* 堆的最大容量 */
};
typedef Heap MaxHeap;    /* 最大堆 */
typedef Heap MinHeap;   /* 最小堆 */
#define MAXDATA 1000   /* 该值应根据具体情况定义为大于堆中所有可能元素的值 */

MaxHeap CreateHeap( int MaxSize )         // 创建容量为MaxSize的空的最大堆 
{
    MaxHeap H = (MaxHeap)malloc(sizeof(struct HNode));
    H->Data = (ElementType *)malloc((MaxSize+1)*sizeof(ElementType));
    H->Size = 0;
    H->Capacity = MaxSize;
    H->Data[0] = MAXDATA;   /* 定义"哨兵"为大于堆中所有可能元素的值*/
    return H;
}
bool IsFull( MaxHeap H )
{
    return (H->Size == H->Capacity);
}
bool Insert( MaxHeap H, ElementType X )
{
          /* 将元素X插入最大堆H,其中H->Data[0]已经定义为哨兵 */
    int i;
    if ( IsFull(H) )
    {
        printf("最大堆已满");
        return false;
    }
    i = ++H->Size;                 /* i指向插入后堆中的最后一个元素的位置 */
    for ( ; H->Data[i/2] < X; i/=2 )
        H->Data[i] = H->Data[i/2];     /* 上滤X */
    H->Data[i] = X;                   /* 将X插入 */
    return true;
}
#define ERROR -1             /* 错误标识应根据具体情况定义为堆中不可能出现的元素值 */
bool IsEmpty( MaxHeap H )
{
    return (H->Size == 0);
}
ElementType DeleteMax( MaxHeap H )
{
               /* 从最大堆H中取出键值为最大的元素,并删除一个结点 */
    int Parent, Child;
    ElementType MaxItem, X;
    if ( IsEmpty(H) )
    {
        printf("最大堆已为空");
        return ERROR;
    }
    MaxItem = H->Data[1];       /* 取出根结点存放的最大值 */     
                               /* 用最大堆中最后一个元素从根结点开始向上过滤下层结点 */
    X = H->Data[H->Size--];   /* 注意当前堆的规模要减小 */
    for( Parent=1; Parent*2<=H->Size; Parent=Child )
    {
        Child = Parent * 2;
        if( (Child!=H->Size) && (H->Data[Child]<H->Data[Child+1]) )
            Child++;                /* Child指向左右子结点的较大者 */
        if( X >= H->Data[Child] ) 
            break;                /* 找到了合适位置 */
        else                     /* 下滤X */
            H->Data[Parent] = H->Data[Child];
    }
    H->Data[Parent] = X;
    return MaxItem;
}
/*----------- 建造最大堆 -----------*/
void PercDown( MaxHeap H, int p )
{
                          /* 下滤:将H中以H->Data[p]为根的子堆调整为最大堆 */
    int Parent, Child;
    ElementType X;
    X = H->Data[p];    /* 取出根结点存放的值 */
    for( Parent=p; Parent*2<=H->Size; Parent=Child )
    {
        Child = Parent * 2;
        if( (Child!=H->Size) && (H->Data[Child]<H->Data[Child+1]) )
            Child++;         /* Child指向左右子结点的较大者 */
        if( X >= H->Data[Child] ) 
            break;         /* 找到了合适位置 */
        else              /* 下滤X */
            H->Data[Parent] = H->Data[Child];
    }
    H->Data[Parent] = X;
}
void BuildHeap( MaxHeap H )
{
       /* 调整H->Data[]中的元素,使满足最大堆的有序性  */
      /* 这里假设所有H->Size个元素已经存在H->Data[]中 */
    int i;
    /* 从最后一个结点的父节点开始,到根结点1 */
    for( i = H->Size/2; i>0; i-- )
        PercDown( H, i );
}




int main()
{
    printf("Hello world!\n");
    return 0;
}

 

    原文作者:满二叉树
    原文地址: https://blog.csdn.net/winner647520/article/details/80500971
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞