C语言二叉树基本操作

二叉树的抽象数据类型定义

类型名称: 二叉树
数据对象集:一个有穷的结点集合。
    若不为空,则由根节点和其左,右二叉子树组成。

操作集:BT ∈BinTree,Itlm ∈ElementType,重要操作有:
1.Boolean IsEmpty(BinTree BT):判断BT是否为空;
2.void Traversal(BinTree BT):遍历,按某顺序访问每个结点;
3.BinTree CreatBinTree():创建一个二叉树。


常见的遍历方法有:
void PreOrderTraversal(BinTree BT):先序——根、左子树 、右子树;
void InOrderTraversal(BinTree BT):中序——左子树、根 、右子树;
void PostOrderTraversal(BinTree BT):后序—— 左子树 、右子树、根;
void LevelOrderTraversal(BinTree BT):层次遍历,从上到下,从左到右;
 


二叉树的链表存储
typedef struct TreeNode *BinTree;
typedef BinTree Position;
struct TreeNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
}; 
 

二叉树的遍历
//递归遍历 
(1)先序遍历
void PreOrderTraversal(BinTree BT)//先序——根、左子树 、右子树;
{
    if(BT)
    {
        printf("%d ",BT->Data);
        PreOrderTraversal(BT->Left);
        PreOrderTraversal(BT->Right);
    }
 } 

(2)中序遍历 
void InOrderTraversal(BinTree BT)//中序——左子树、根 、右子树; 
{
    if(BT)
    {        
        InOrderTraversal(BT->Left);
        printf("%d ",BT->Data);
        InOrderTraversal(BT->Right);
    }

(3)后序遍历 
void PostOrderTraversal(BinTree BT)//后序—— 左子树 、右子树、根;
{
    if(BT)
    {        
        PostOrderTraversal(BT->Left); 
        PostOrderTraversal(BT->Right);
        printf("%d ",BT->Data);
    }

//非递归遍历算法
(4)中序遍历非递归遍历算法
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->Data);
            T=T->Right;
        }
    }    

(5)后序遍历非递归遍历算法 
void PostOrderTraversal(Bintree BT) {  //给节点增加访问次数的属性Visit,初始化为0
    Bintree T BT;
    Stack S = CreateStack(Maxsize);
    while (T || !IsEmpty(S)) {
        while (T) {
            if (T->Visit == 0) {//虽然没必要判断,为便于理解
                T->Visit++;
                Push(S, T);  //第一次入栈,不访问
            }
            T = T->left;   //转向左子树
        }
        if (!IsEmpty(S)) {
            T = Pop(s);
            if (T->Visit == 2)    {
                printf("%d", T->Data);//第三次碰到它,访问节点,可以彻底从堆栈弹出了
                T = NULL;//左右子数均已经访问过
            }
            else {
                T->Visit++;
                Push(S, T);  //第二次入栈,不访问,(相当于T没有出栈)
                T = T->Right;  //转向右子树
            }
        }
    }

(6)层序遍历 
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 );
    }
}


(7)输出二叉树的叶子结点 
void PreOrderTraversal(BinTree BT)//先序——根、左子树 、右子树;
{
    if(BT)
    {
        if (!BT->Left&&!BT->Right) 
            printf("%d ",BT->Data);
        PreOrderTraversal(BT->Left);
        PreOrderTraversal(BT->Right);
    }
 } 
 

(8)二叉树的高度 
int PostOrderGetHight(BinTree BT)//后序—— 左子树 、右子树、根;
{
    int HL,HR,MaxH;
    if(BT)
    {        
        HL=PostOrderGetHight(BT->Left); 
        HR=PostOrderGetHight(BT->Right);
        MaxH=(HL>HR)?HL:HR;
        return (MaxH+1);
    }
    else return 0;

(9)二叉树的表示
//结构数组表示二叉树
#define MaxTree 10
#define ElementType char
#define Tree int 
#define Null -1

struct TreeNode
{
    ElementType Element;
    Tree Left;
    Tree Right;
}T1[MaxTree],T2[MaxTree]; 


(10)交换二叉树 
#include<stdio.h>
#include<stdlib.h>

//二叉树的结点类型;

typedef struct tree    
{
    char ch;
    struct tree *lchild;
    struct tree *rchild;
}BitTree;

//创建树;

BitTree *CreateTree()
{
    BitTree *bt;
    char str;
    scanf("%c",&str);
    if(str=='#')
        return NULL;
    else
    {
        bt=(BitTree *)malloc(sizeof(BitTree));
        bt->ch=str;
        bt->lchild=CreateTree();
        bt->rchild=CreateTree();
        return bt;
    }
}

//交换左右二叉树;

void Exchange(BitTree *bt)
{
    if(bt->lchild==NULL&&bt->rchild==NULL)
        printf("树为空\n");
    else    //三种情况,1.都不为空,2.左为空,3.右为空;
    {
        //交换左右子树;
        BitTree *temp=bt->lchild;
        bt->lchild=bt->rchild;
        bt->rchild=temp;
    }

    //如果交换后的这个结点左子树不为空,则继续向下寻找可以交换的结点;
    if(bt->lchild)            
        Exchange(bt->lchild);
    if(bt->rchild)
        Exchange(bt->rchild);
}

int main()
{
    BitTree *bt;
    //创建二叉树;
    printf("请以先序序列输入需要交换的二叉树:\n");
    bt=CreateTree();
    //交换左右子树;
    Exchange(bt);
}

猜你喜欢

转载自blog.csdn.net/SignalFire/article/details/109430934
今日推荐