孩子兄弟表示法(二叉链表树)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/RowandJJ/article/details/28111643

考虑下面这森林:


如果用孩子兄弟表示法可以表示为:


顾名思义,孩子兄弟表示法的每个节点有两个指针域,一个指向其长子,另一个指向其兄弟.

实现:
/**************************************************
树的孩子兄弟表示法(二叉链表树)
by Rowandjj
2014/5/25
**************************************************/
#include<iostream>
using namespace std;

typedef char ElemType; 
//--------二叉链表(孩子-兄弟)存储表示-------
typedef struct _TREENODE_
{
    struct _TREENODE_ *pFirstChild;
    struct _TREENODE_ *pNextSibling;
    ElemType data;
}TreeNode,*pTreeNode,**ppTreeNode;

//----------辅助队列-------------------
typedef struct _QUEUENODE_
{
    struct _QUEUENODE_ *pNext;
    pTreeNode data;
}QueueNode,*pQueueNode;

typedef struct _QUEUE_
{
    pQueueNode pHead;
    pQueueNode pTail;
    int nodeCount;
}Queue,*pQueue;

//-----------队列操作定义-----------------------
void InitQueue(pQueue pQueueTemp);
void Enqueue(pQueue pQueueTemp,pTreeNode pTreeNodeTemp);
void Dequeue(pQueue pQueueTemp,ppTreeNode ppTreeNodeTemp);
bool IsQueueEmpty(Queue QueueTemp);
void DestroyQueue(pQueue pQueueTemp);


//------------二叉树操作定义--------------------

void CreateTree(ppTreeNode ppTreeNodeTemp);
void DestroyTree(ppTreeNode ppTreeNodeTemp);
int GetDepth(pTreeNode pTreeNodeTemp);

void PreTravel(pTreeNode pTreeNodeTemp);
void PostTravel(pTreeNode pTreeNodeTemp);
void MidTravel(pTreeNode pTreeNodeTemp);
void LevelTravel(pTreeNode pTreeNodeTemp);

pTreeNode Point(pTreeNode pTreeNodeTemp,ElemType e);
ElemType GetParent(pTreeNode pTreeNodeTemp,ElemType e);

void InsertTree(ppTreeNode ppTreeNodeTemp,ElemType data,int i,pTreeNode pSub);//将psub插入到ppTreeNodeTemp中的值为data的节点的第i个子树
void DeleteTree(ppTreeNode ppTreeNodeTemp,ElemType data,int i);//删除ppTreeNodeTemp中的值为data的节点的第i个子树


//---------队列操作实现---------------
void InitQueue(pQueue pQueueTemp)
{
    pQueueTemp->pHead = pQueueTemp->pTail = (pQueueNode)malloc(sizeof(QueueNode));
    if(pQueueTemp->pHead == NULL)
    {
        return;
    }
    pQueueTemp->nodeCount = 0;
    pQueueTemp->pHead->pNext = NULL;
}
void Enqueue(pQueue pQueueTemp,pTreeNode pTreeNodeTemp)
{
    if(pQueueTemp == NULL)
    {
        return;
    }
    pQueueNode pNew = (pQueueNode)malloc(sizeof(QueueNode));
    if(pNew == NULL)
    {
        return;
    }
    pNew->data = pTreeNodeTemp;
    pNew->pNext = NULL;

    pQueueTemp->pTail->pNext = pNew;
    pQueueTemp->pTail = pNew;
    pQueueTemp->nodeCount++;
}
void Dequeue(pQueue pQueueTemp,ppTreeNode ppTreeNodeTemp)
{
    if(pQueueTemp == NULL)
    {
        return;
    }
    pQueueNode pDel = pQueueTemp->pHead->pNext;
    pQueueTemp->pHead->pNext = pDel->pNext;
    if(pDel == pQueueTemp->pTail)
    {
        pQueueTemp->pTail = pQueueTemp->pHead;
    }
    *ppTreeNodeTemp = pDel->data;
    free(pDel);
    pQueueTemp->nodeCount--;
}
bool IsQueueEmpty(Queue QueueTemp)
{
    return QueueTemp.nodeCount == 0;
}
void DestroyQueue(pQueue pQueueTemp)
{
    if(pQueueTemp != NULL)
    {
        pQueueNode pTravel = pQueueTemp->pHead->pNext;
        while(pTravel != NULL)
        {
            pQueueTemp->pHead->pNext = pTravel->pNext;
            free(pTravel);
            pTravel = pQueueTemp->pHead->pNext;
        }
        free(pQueueTemp->pHead);
        pQueueTemp->nodeCount = 0;
    }
}

//------------二叉树操作实现-------------------------

void CreateTree(ppTreeNode ppTreeNodeTemp)//创建
{
    char szBuffer[20];
    char a;
    cout<<"输入根节点:";
    cin>>a;
    Queue queue;
    InitQueue(&queue);
    if(a != '#')
    {
        *ppTreeNodeTemp = (pTreeNode)malloc(sizeof(TreeNode));
        (*ppTreeNodeTemp)->data = a;
        (*ppTreeNodeTemp)->pNextSibling = NULL;
        Enqueue(&queue,*ppTreeNodeTemp);//入队根节点

        pTreeNode pTemp,pTemp1;
        while(!IsQueueEmpty(queue))
        {
            Dequeue(&queue,&pTemp);
            cout<<"输入"<<pTemp->data<<"的孩子节点:";
            cin>>szBuffer;
            if(szBuffer[0] != '#')
            {
                pTemp->pFirstChild = (pTreeNode)malloc(sizeof(TreeNode));
                
                pTemp->pFirstChild->data = szBuffer[0];
    
                pTemp1 = pTemp->pFirstChild;
                for(int i = 1; i < strlen(szBuffer); i++)
                {
                    pTemp1->pNextSibling = (pTreeNode)malloc(sizeof(TreeNode));
                    Enqueue(&queue,pTemp1);
                    pTemp1->pNextSibling->data = szBuffer[i];
                        
                    pTemp1 = pTemp1->pNextSibling;
                }
                pTemp1->pNextSibling = NULL;
                Enqueue(&queue,pTemp1);

            }else
            {
                pTemp->pFirstChild = NULL;
            }
            
        }

    }else
    {
        *ppTreeNodeTemp = NULL;
    }

}
void DestroyTree(ppTreeNode ppTreeNodeTemp)
{
    if(*ppTreeNodeTemp != NULL)
    {
        if((*ppTreeNodeTemp)->pFirstChild != NULL)
        {
            DestroyTree(&(*ppTreeNodeTemp)->pFirstChild);    
        }
        if((*ppTreeNodeTemp)->pNextSibling != NULL)
        {
            DestroyTree(&(*ppTreeNodeTemp)->pNextSibling);
        }
        free(*ppTreeNodeTemp);
        *ppTreeNodeTemp = NULL;
    }
}


int GetDepth(pTreeNode pTreeNodeTemp)
{
    if(pTreeNodeTemp == NULL)
    {
        return 0;
    }
    if(pTreeNodeTemp->pFirstChild == NULL)
    {
        return 1;
    }
    int depth,max = 0;
    pTreeNode pTemp = pTreeNodeTemp->pFirstChild;
    for(;pTemp != NULL; pTemp = pTemp->pNextSibling)
    {
        depth = GetDepth(pTemp);
        if(depth > max)
        {
            max = depth;
        }
    }
    return max+1;
}

void PreTravel(pTreeNode pTreeNodeTemp)
{
    if(pTreeNodeTemp)
    {
        cout<<pTreeNodeTemp->data<<" ";
        PreTravel(pTreeNodeTemp->pFirstChild);
        PreTravel(pTreeNodeTemp->pNextSibling);
    }
}

void MidTravel(pTreeNode pTreeNodeTemp)
{
    if(pTreeNodeTemp)
    {
        MidTravel(pTreeNodeTemp->pFirstChild);
        cout<<pTreeNodeTemp->data<<" ";
        MidTravel(pTreeNodeTemp->pNextSibling);
    }
}


void PostTravel(pTreeNode pTreeNodeTemp)
{
    if(pTreeNodeTemp)
    {
        PostTravel(pTreeNodeTemp->pFirstChild);
        PostTravel(pTreeNodeTemp->pNextSibling);
        cout<<pTreeNodeTemp->data<<" ";
    }
}

pTreeNode Point(pTreeNode pTreeNodeTemp,ElemType e)
{
    Queue queue;
    InitQueue(&queue);
    if(pTreeNodeTemp != NULL)
    {
        Enqueue(&queue,pTreeNodeTemp);

        pTreeNode pTemp;
        while(!IsQueueEmpty(queue))
        {
            Dequeue(&queue,&pTemp);
            if(pTemp->data == e)
            {
                DestroyQueue(&queue);
                return pTemp;
            }else
            {
                pTreeNode pSibling = NULL;
                if(pTemp->pFirstChild != NULL)
                {
                    Enqueue(&queue,pTemp->pFirstChild);//入队长子
                     pSibling = pTemp->pFirstChild->pNextSibling;
                }
                 
                while(pSibling != NULL)
                {
                    Enqueue(&queue,pSibling);//入队兄弟
                    pSibling = pSibling->pNextSibling;
                }
            }
        }

    }
    return NULL;
}

ElemType GetParent(pTreeNode pTreeNodeTemp,ElemType e)
{
    Queue queue;
    InitQueue(&queue);
    
    if(pTreeNodeTemp != NULL)
    {
        if(pTreeNodeTemp->data == e)
        {
            return -1;
        }
        Enqueue(&queue,pTreeNodeTemp);

        pTreeNode pTemp,pTemp1;
        while(!IsQueueEmpty(queue))
        {
            Dequeue(&queue,&pTemp);
            if(pTemp->pFirstChild)
            {
                if(pTemp->pFirstChild->data == e)
                {
                    return pTemp->data;
                }
                pTemp1 = pTemp;
                
                Enqueue(&queue,pTemp->pFirstChild);//入队长子
                pTemp = pTemp->pFirstChild;

                while(pTemp->pNextSibling)
                {
                    pTemp = pTemp->pNextSibling;
                    if(pTemp->data == e)
                    {
                        return pTemp1->data;
                    }
                    Enqueue(&queue,pTemp);//入队兄弟
                }
            }
        }
    }

    return -1;
}

void LevelTravel(pTreeNode pTreeNodeTemp)//层次遍历
{
    Queue queue;
    InitQueue(&queue);

    if(pTreeNodeTemp != NULL)
    {
        cout<<pTreeNodeTemp->data<<" ";
        Enqueue(&queue,pTreeNodeTemp);
        
        pTreeNode pTemp;
        while(!IsQueueEmpty(queue))
        {
            Dequeue(&queue,&pTemp);
            
            if(pTemp->pFirstChild != NULL)
            {
                pTemp = pTemp->pFirstChild;
                cout<<pTemp->data<<" ";
                Enqueue(&queue,pTemp);//入队长子
                while(pTemp->pNextSibling != NULL)
                {
                    pTemp = pTemp->pNextSibling;
                    cout<<pTemp->data<<" ";
                    Enqueue(&queue,pTemp);
                }
            }

        }    
    }
}

void InsertTree(ppTreeNode ppTreeNodeTemp,ElemType data,int i,pTreeNode pSub)
{
    if(*ppTreeNodeTemp == NULL)
    {
        return;
    }

    pTreeNode pTreeNodeTemp = Point(*ppTreeNodeTemp,data);
    if(pTreeNodeTemp != NULL)
    {
        if(i==1)
        {
            pSub->pNextSibling = pTreeNodeTemp->pFirstChild;
            pTreeNodeTemp->pFirstChild = pSub;
        }else
        {
            int j = 2;
            pTreeNodeTemp = pTreeNodeTemp->pFirstChild;
            while (j < i && pTreeNodeTemp)
            {
                pTreeNodeTemp = pTreeNodeTemp->pNextSibling;
                j++;
            }
            if(j == i)
            {
                pSub->pNextSibling = pTreeNodeTemp->pNextSibling;
                pTreeNodeTemp->pNextSibling = pSub;
            }else
            {
                return;
            }
        }
    }
}

void DeleteTree(ppTreeNode ppTreeNodeTemp,ElemType data,int i)
{
    if(*ppTreeNodeTemp == NULL)
    {
        return;
    }
    pTreeNode pTemp;
    pTreeNode pTreeNodeTemp = Point(*ppTreeNodeTemp,data);
    if(pTreeNodeTemp != NULL)
    {    
        if(i == 1)//删除长子
        {
            pTemp = pTreeNodeTemp->pFirstChild;
            pTreeNodeTemp->pFirstChild = pTemp->pNextSibling;
            pTemp->pNextSibling = NULL;
            DestroyTree(&pTemp);
        }else
        {
            pTreeNodeTemp = pTreeNodeTemp->pFirstChild;
            int j = 2;
            while(j < i && pTreeNodeTemp)
            {
                pTreeNodeTemp = pTreeNodeTemp->pNextSibling;    
                j++;
            }

            if(j == i)
            {
                pTemp = pTreeNodeTemp->pNextSibling;
                pTreeNodeTemp->pNextSibling = pTemp->pNextSibling;
                pTemp->pNextSibling = NULL;
                DestroyTree(&pTemp);
            }
        }
    }
}




猜你喜欢

转载自blog.csdn.net/RowandJJ/article/details/28111643