孩子兄弟表示法(二叉链表树) 时间 2014-06-02 16:32:17 CSDN博客 原文 http://blog.csdn.net/chdjj/article/details/2811164

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

考虑下面这森林:

 

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

 

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


实现:
/**************************************************
树的孩子兄弟表示法(二叉链表树)
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);
			}
		}
	}
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值