关于数据结构中二叉树

版权声明:欢迎转载!拒绝抄袭. https://blog.csdn.net/qq_36257146/article/details/80215238
#include <stdio.h>
#include <stdlib.h>
#include <string.h>




typedef char element;
typedef struct BiTNode
{
    element data;
    struct BiTNode *lchild,*rchild;
} BiTNode,*BiTree;


struct queueNode
{
    BiTree data;  /*define data as char*/
    struct queueNode* nextPtr;/*queueNode pointer*/
};


typedef struct queueNode QueueNode;
typedef QueueNode * QueueNodePtr;


///队列的
void Enqueue(QueueNodePtr * headPtr, QueueNodePtr * tailPtr, BiTree value);
int isEmptyQueue(QueueNodePtr headPtr);
void dequeue(QueueNodePtr*headPtr,QueueNodePtr * tailPtr);
BiTree front(QueueNodePtr * headPtr,QueueNodePtr * tailPtr);


void CreateBiTree(BiTree *T);
void printBiTreePre(BiTree T);
void destroyBiTree(BiTree *T);
int isEmpty(BiTree T);
int similarity(BiTree T1,BiTree T2);
void getKValue(BiTree T,int count);
int getLeaf(BiTree T);
void changeTree(BiTree * T1);
void printBiTreeByFloor(BiTree T);
int judgeAbsolute(BiTree T);
BiTree front(QueueNodePtr * headPtr,QueueNodePtr * tailPtr);
void PrintTree(BiTree Boot,int nLayer);
void createTreeByPreMid(BiTree *T);
void TrulyCreateByPreMid(BiTree*T,char pre[],char mid[]);




int main()
{
    BiTree T1 = NULL;
    //createTreeByPreMid(&T);




    CreateBiTree(&T1);
    //printBiTreeByFloor(T1);
    PrintTree(T1,0);
    printf("\n\n");
    changeTree(&T1);
    PrintTree(T1,0);


    ///ab##c##        abdf###e##ch###
    destroyBiTree(&T1);
    return 0;
}


//得到二叉树的高度
int height(BiTree T)
{
   if(!T)//如果为空
   {
       return 0;
   }
   else
   {
       return ( height(T->lchild)>height(T->rchild) )? height(T->lchild)+1 : height(T->rchild)+1;
   }
}


void getParent(BiTree T,char value)
{
    static int flag = 0;
    if(T==NULL)//如果根节点为空,那么没有双亲
    {
        return ;
    }
    else
    {
        if(T->data == value)//如果根节点就是要找的值,显然也咩有双亲
        {
            return ;
        }
        if(T->lchild)
        {
            if((T->lchild)->data == value)
            {
                printf("双亲是%c\n",T->data);
                flag = 1;
                return ;//如果根节点就是双亲的话
            }
        }
        if(T->rchild)
        {
            if((T->rchild)->data == value)
            {
                printf("双亲是%c\n",T->data);
                flag = 1;
                return ;//如果根节点就是双亲的话
            }


        }
        getParent(T->lchild,value);//从左子树找
        if(flag == 0)
        {


           getParent(T->rchild,value);
        }


    }


}






int isEmptyArray(char s[])
{
    return strlen(s)==0;
}




//创建二叉树通过前序和中序
void createTreeByPreMid(BiTree *T)
{
    char pre[30];
    char mid[30];
    printf("请输入前序的序列:\n");//ABDEGHCFI
    scanf("%s",pre);
    printf("请输入中序的序列:\n");//DBGEHACIF
    scanf("%s",mid);


    TrulyCreateByPreMid(T,pre,mid);
    printBiTreeByFloor(*T);
    printf("\n");
    printBiTreePre(*T);
    printf("\n");
    PrintTree(*T,0);
    destroyBiTree(T);




}


//把前序分为两半
void SubPre(char pre[],int leftLen,int rightLen,char left[],char right[])
{
    int i;
    for(i = 0;i<strlen(pre);i++)//把pre第一个节点删掉
    {
        pre[i] = pre[i+1];
    }
    //把左边的分出来
    for(i = 0;i<leftLen;i++)
    {
        left[i] = pre[i];
    }
    left[i] = '\0';
    int j;
    for(j = 0;j<rightLen;j++)
    {
        right[j] = pre[i+j];
    }
    right[j] = '\0';


}


//把中序分为两半
void SubMid(char mid[],char left[],char right[],char head)
{
    //记得加\n
    int i = 0;
    while(mid[i]!=head)
    {
        left[i] = mid[i];
        i++;
    }
    left[i++] = '\0';
    //printf("left is %s\n",left);
    int j = 0;
    for(i;i<strlen(mid);i++)
    {
        right[j++] = mid[i];
    }
    right[j] = '\0';
}


void TrulyCreateByPreMid(BiTree*T,char pre[],char mid[])
{
    if(!isEmptyArray(pre))
    {
        char value = pre[0];//得到当前的第一个节点
        *T = (BiTree)malloc(sizeof(BiTNode));  //创建节点
        ///给结点赋初值
        (*T)->data = value;
        (*T)->lchild = NULL;
        (*T)->rchild = NULL;
        char preLeft[30],preRight[30],midLeft[30],midRight[30];
        SubMid(mid,midLeft,midRight,value);//把mid分成左右两部分
        printf("分完mid,left is %s,right is %s\n",midLeft,midRight);
        SubPre(pre,strlen(midLeft),strlen(midRight),preLeft,preRight);
        printf("分完pre,left is %s,right is %s\n",preLeft,preRight);
        TrulyCreateByPreMid(&((*T)->lchild),preLeft,midLeft);
        TrulyCreateByPreMid(&((*T)->rchild),preRight,midRight);


    }


}


void CreateBiTree(BiTree *T)
{
    char value;
    scanf("%c",&value);
    if(value =='#')
    {
        *T = NULL;
        return ;
    }
    else
    {
        *T = (BiTree)malloc(sizeof(BiTNode));
        (*T)->data = value;
        CreateBiTree( &((*T)->lchild) );
        CreateBiTree( &((*T)->rchild) );


    }
}


void printBiTreePre(BiTree T)
{
    if(T)
    {
        printf("%c ",T->data);
        printBiTreePre(T->lchild);
        printBiTreePre(T->rchild);
    }
}


void destroyBiTree(BiTree *T)
{
    BiTree p = *T;
    if(p)
    {


        destroyBiTree(&(p->lchild));
        destroyBiTree(&(p->rchild));
        //printf("删除%c\n",p->data);
        free(p);
        p = NULL;
    }
}


int isEmpty(BiTree T)
{
    return T == NULL;
}


int similarity(BiTree T1,BiTree T2)
{
    if( (isEmpty(T1)&&!isEmpty(T2)) || (isEmpty(T2)&&!isEmpty(T1)))//如果不一样
        return 0;
    else if(isEmpty(T1)&&isEmpty(T2))
        return 1;
    else
    {
        return (similarity(T1->lchild,T2->lchild)&&similarity(T1->rchild,T2->rchild));
    }


}


void getKValue(BiTree T,int count)
{
    static int i;//记数现在已经有多少个结点
    if(T&&count!=i)//不为空且不满足条件
    {
        i++;
        if(i==count)
        {
            printf("%c\n",T->data);
        }
        else
        {
            getKValue(T->lchild,count);
            getKValue(T->rchild,count);
        }


    }
}


int getLeaf(BiTree T)
{
    static int count;
    if(T)
    {
        if(isEmpty(T->lchild)&&isEmpty(T->rchild))
        {
            count++;
        }
        else
        {
            getLeaf(T->lchild);
            getLeaf(T->rchild);
        }
    }
    return count;
}


void changeTree(BiTree * T1)
{
    if(!isEmpty(*T1))//(isEmpty((*T1)->lchild)&&isEmpty((*T1)->rchild) )
    {
        BiTree p = (*T1)->lchild;
        (*T1)->lchild = (*T1)->rchild;
        (*T1)->rchild = p;
        changeTree( &((*T1)->lchild) );
        changeTree( &((*T1)->rchild) );
    }
}


void printBiTreeByFloor(BiTree T)
{
    QueueNodePtr headPtr = NULL; /*initialize headPtr*/
    QueueNodePtr tailPtr = NULL; /*initialize tailPtr*/
    if(!isEmpty(T))
    {
        Enqueue(&headPtr,&tailPtr,T);
        //printf("%c ",T->data);
        while(!isEmptyQueue(headPtr))//当队列不为空时
        {
            BiTree q = front(&headPtr,&tailPtr);
            printf("%c  ",q->data);
            if(!isEmpty(q->lchild))
            {
                Enqueue(&headPtr,&tailPtr,q->lchild);
            }
            if(!isEmpty(q->rchild))
            {
                Enqueue(&headPtr,&tailPtr,q->rchild);
            }
            dequeue(&headPtr,&tailPtr);
            //printf("is empty!  %d\n",isEmptyQueue(headPtr));
        }
    }
}


//得到前面的值
BiTree front(QueueNodePtr * headPtr,QueueNodePtr * tailPtr)
{
    BiTree value;
    value = (*headPtr)->data;
    return value;
}


void Enqueue(QueueNodePtr * headPtr, QueueNodePtr * tailPtr, BiTree value)
{
    QueueNodePtr newPtr;/*pointer to new node*/


    newPtr = malloc(sizeof(QueueNode));
    //printf("no is Enqueue\n");
    if(newPtr!=NULL)
    {
        newPtr->data = value;
        newPtr->nextPtr = NULL;
        //printf("the value is     %c\n",value->data);
        /*if empty, insert node at head*/
        if(isEmptyQueue(*headPtr))
        {
            *headPtr = newPtr;
        }
        else/*insert node at end*/
        {
            (*tailPtr)->nextPtr = newPtr;
        }
        *tailPtr = newPtr;
    }/*end if*/


    else
    {
        printf("fail.\n\n");
    }/*end else*/
}/*end function Enqueue*/




/*delect node from head to tail*/
void dequeue(QueueNodePtr * headPtr,QueueNodePtr * tailPtr)
{
    /** LNode value;**/
    QueueNodePtr tempPtr = *headPtr;//point to the head
    *headPtr = tempPtr->nextPtr;
//printf("NULL\n");
    if(*headPtr == NULL)//the head is NULL
    {


        *tailPtr = NULL;
    }


    free(tempPtr);//free the temp


    // return value;//return the value
}//end function dequeue


int isEmptyQueue(QueueNodePtr headPtr)
{
    return headPtr==NULL;
}


//判断完全二叉树
int judgeAbsolute(BiTree T)
{
    static int flag = 0;
    QueueNodePtr headPtr = NULL;
    QueueNodePtr tailPtr = NULL;
    if(!isEmpty(T))
    {


        Enqueue(&headPtr,&tailPtr,T);
        printf("插入成功:\n");
        while(!isEmptyQueue(headPtr))
        {
            BiTree q = front(&headPtr,&tailPtr);
            printf("now the point is %c\n",q->data);
            if( (!isEmpty(q->lchild)||!isEmpty(q->rchild)) &&flag)
            {
                printf("当右结点为空时:\n");
                return 0;
            }
            if(!isEmpty(q->lchild))
            {
                printf("左结点不为空:\n");
                Enqueue(&headPtr,&tailPtr,q->lchild);
            }
            if(!isEmpty(q->rchild))
            {
                printf("右结点不为空:\n");
                Enqueue(&headPtr,&tailPtr,q->rchild);
            }
            if(isEmpty(q->lchild)&&!isEmpty(q->rchild))//如果左结点为空,右结点不为空
            {


                return 0;
            }
            else if( isEmpty(q->rchild) )//两个都是空的或者右边是空的,有待商榷
            {
                flag = 1;
            }
            dequeue(&headPtr,&tailPtr);
        }
    }
    return 1;


}




void PrintTree(BiTree Boot,int nLayer)  //按竖向树状打印的二叉树 //
{
    if(Boot)
    {
        int i;
        PrintTree(Boot->rchild,nLayer+1);
        for(i = 0;i<nLayer;i++)
        {
            printf("  ");
        }
        printf("%c\n",Boot->data);
        PrintTree(Boot->lchild,nLayer+1);
    }


}





猜你喜欢

转载自blog.csdn.net/qq_36257146/article/details/80215238