データ構造学習ノート---ツリー


1.引用
1本の木がどれだけフォークを持っていても、長男とその下の兄弟が一番多い.このような定義によれば,各ノードの構造は二叉に統一される.
チェーン
時計の構造ができた.これにより、ノードの操作が容易になります.
2.ツリーの二叉チェーン(子供-兄弟)ストレージ
#include "ds.h"
typedef char TElemType;
TElemType Nil=' '; //       

typedef struct CSNode
{
	TElemType 	data;
	CSNode 		*firstchild, *nextsibling;
}CSNode, *CSTree;

#define 	ClearTree 		DestroyTree	//       

typedef 	CSTree 		QElemType;

typedef struct QNode{
	QElemType 		data;
	struct QNode 	*next;
}*QueuePtr;

struct LinkQueue{
	QueuePtr 	front, rear;
};

void InitQueue(LinkQueue &Q);
void DestroyQueue(LinkQueue &Q);
void ClearQueue(LinkQueue &Q);
Status QueueEmpty(LinkQueue Q);
void EnQueue(LinkQueue &Q, QElemType e);
Status DeQueue(LinkQueue &Q, QElemType &e);


//          
void InitQueue(LinkQueue &Q)
{
	Q.front = (QueuePtr)malloc(sizeof(QNode));
	if (!Q.front) exit(OVERFLOW);
	
	Q.front->next = NULL;
	Q.rear = Q.front;
		
}
void DestroyQueue(LinkQueue &Q)
{
	QueuePtr q, p = Q.front;
	
	while (p)
	{
		q = p->next;
		free(p);
		p = q;
	}
	
	Q.front = Q.rear = NULL;
}
void ClearQueue(LinkQueue &Q)
{
	QueuePtr q, p = Q.front->next;
	
	while (p)
	{
		q = p->next;
		free(p);
		p = q;
	}
	Q.front->next = NULL;
	Q.rear = Q.front;
}
Status QueueEmpty(LinkQueue Q)
{
	if (Q.front == Q.rear)
		return TRUE;
	else
		return FALSE;
}


void EnQueue(LinkQueue &Q, QElemType e)
{
	QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
	if (!p) exit(OVERFLOW);
	
	p->next = NULL;
	memcpy(&(p->data), &e, sizeof(QElemType));
	Q.rear->next = p;
	Q.rear = p;
}
Status DeQueue(LinkQueue &Q, QElemType &e)
{
	QueuePtr p = Q.front, q;
	if (Q.front == Q.rear)
		return FALSE;
	
	q = p->next;
	memcpy(&e, &(q->data), sizeof(QElemType));
	p->next = q->next;
	if (Q.rear == q)
		Q.rear = Q.front;
	free(q);
	
	return OK;
}




//       —          T
void PreOrderTraverse(CSTree T, void(*Visit)(TElemType))
{
	if (T)
	{
		Visit(T->data);	//       
		PreOrderTraverse(T->firstchild, Visit);		//          
		PreOrderTraverse(T->nextsibling, Visit);	//              
	}
}

void InitTree(CSTree &T)
{
	T = NULL;
}

void DestroyTree(CSTree &T)
{
	if (T)
	{
		if (T->firstchild)
			DestroyTree(T->firstchild);
		if (T->nextsibling)
			DestroyTree(T->nextsibling);
		free(T);
		T = NULL;
	}
}

void CreateTree(CSTree &T)
{
	char  		c[20];
	CSTree 		p, p1;
	LinkQueue	q;
	int 		i, l;
	InitQueue(q);
	
	printf("      (   ,    ): ");
	scanf("%c%*c", &c[0]);
	
	if (c[0] != Nil)	//    
	{
		T = (CSTree)malloc(sizeof(CSNode));	//      
		T->data = c[0];
		T->nextsibling = NULL;
		EnQueue(q, T);						//         
		
		while (!QueueEmpty(q))				//    
		{
			DeQueue(q, p);					//          
			printf("          %c     : ",p->data);
			gets(c);
			l = strlen(c);
			if (l > 0)						//    
			{
				p1 = p->firstchild = (CSTree)malloc(sizeof(CSNode));	//       
				p1->data = c[0];
				for (i = 1; i < l; i++)
				{
					p1->nextsibling = (CSTree)malloc(sizeof(CSNode));	//          
					EnQueue(q, p1);			//        
					p1 = p1->nextsibling;
					p1->data = c[i];
				}
				p1->nextsibling = NULL;
				EnQueue(q, p1);				//         
			}
			else
				p->firstchild = NULL;		//       
		}
	}
	else
     	T = NULL; //   
}

//     : T  。    : T   ,   TURE,    FALSE
Status TreeEmpty(CSTree T)
{ 
   	if(T) // T  
     	return FALSE;
   	else
     	return TRUE;
 }
 
//     : T  。    :  T   
int TreeDepth(CSTree T)
{ 
   	CSTree p;
   	int depth, max = 0;
   	if (!T) //   
     	return 0;
   	if (!T->firstchild) //     
     	return 1;
   	for (p = T->firstchild; p; p = p->nextsibling)
   	{ //          
     	depth = TreeDepth(p);
     	if (depth > max)
       		max = depth;
   	}
   	return max + 1; //     =       +1
}

//   p      
TElemType Value(CSTree p)
{ 
   	return p->data;
}

//     : T  。    :  T  
TElemType Root(CSTree T)
{ 
   	if(T)
     	return Value(T);
   	else
     	return Nil;
}

//       (  —  ) T       s      。  
CSTree Point(CSTree T,TElemType s)
{ 
   	LinkQueue q;
   	QElemType a;
   	if(T) //    
   	{
     	InitQueue(q); //      
     	EnQueue(q,T); //      
     	while(!QueueEmpty(q)) //    
     	{
       		DeQueue(q,a); //   ,      a
       		if(a->data==s)
	 			return a;
       		if(a->firstchild) //    
         		EnQueue(q,a->firstchild); //     
       		if(a->nextsibling) //       
         		EnQueue(q,a->nextsibling); //        
     	}
   	}
   	return NULL;
}

//     : T  ,cur_e  T     。    : cur_e value
Status Assign(CSTree &T,TElemType cur_e,TElemType value)
{ 
   	CSTree p;
   	if (T) //    
   	{
     	p = Point(T, cur_e); // p cur_e   
     	if (p) //   cur_e
     	{
       		p->data = value; //    
       		return OK;
     	}
   	}
   	return ERROR; //       
}

//     : T  ,cur_e T     
//     : cur_e T     ,       ,      " "
TElemType Parent(CSTree T,TElemType cur_e)
{  
	CSTree p,t;
   	LinkQueue q;
   	InitQueue(q);
   	if(T) //    
   	{
     	if (Value(T) == cur_e) //      cur_e
       	return Nil;
     	EnQueue(q, T); //      
     	while(!QueueEmpty(q))
     	{
       		DeQueue(q,p);
       		if(p->firstchild) // p   
       		{
         		if(p->firstchild->data==cur_e) //    cur_e
           			return Value(p); //     
         		t=p; //       t
         		p=p->firstchild; // p    
         		EnQueue(q,p); //     
         		while(p->nextsibling) //       
	 			{
           			p=p->nextsibling; // p       
	   				if(Value(p)==cur_e) //       cur_e
             			return Value(t); //     
           			EnQueue(q,p); //        
         		}
       		}
     	}
   	}
   	return Nil; //       cur_e
}

//     : T  ,cur_e T     
//     : cur_e T      ,         ,    " " 
TElemType LeftChild(CSTree T,TElemType cur_e)
{  
	CSTree f;
   	f = Point(T,cur_e); // f    cur_e
   	if(f && f->firstchild) //     cur_e   cur_e   
     	return f->firstchild->data;
   	else
     	return Nil;
}

//     : T  ,cur_e T     
//     : cur_e    ,        ,    " "
TElemType RightSibling(CSTree T,TElemType cur_e)
{  
	CSTree f;
   	f = Point(T,cur_e); // f    cur_e
   	if(f && f->nextsibling) //     cur_e   cur_e    
     	return f->nextsibling->data;
   	else
     	return Nil; //   
}

//     : T  ,p  T     ,1≤i≤p      +1,   c T   
//     :  c T p    i   
//   p           , p       
Status InsertChild(CSTree &T,CSTree p,int i,CSTree c)
{ 
   	int j;
   	if(T) // T  
   	{
     	if(i==1) //   c p   
     	{
       		c->nextsibling=p->firstchild; // p      c      (c    )
       		p->firstchild=c;
     	}
     else //     
     {
       p=p->firstchild; //   p   
       j=2;
       while(p&&j<i)
       {
         p=p->nextsibling;
         j++;
       }
       if(j==i) //       
       {
         c->nextsibling=p->nextsibling;
         p->nextsibling=c;
       }
       else // p       i-1
         return ERROR;
     }
     return OK;
   }
   else // T 
     	return ERROR;
}

//     : T  ,p  T     ,1≤i≤p      
//     :  T p      i   
//   p           , p       
Status DeleteChild(CSTree &T,CSTree p,int i)
{ 
   	CSTree b;
   	int j;
   	if(T) // T  
   	{
    	if(i==1) //     
     	{
       		b=p->firstchild;
       		p->firstchild=b->nextsibling; // p        
       		b->nextsibling=NULL;
       		DestroyTree(b);
     	}
     	else //      
     	{
       		p=p->firstchild; // p    
       		j=2;
       		while(p&&j<i)
       		{
         		p=p->nextsibling;
         		j++;
       		}
       		if(j==i) //    i   
       		{
         		b=p->nextsibling;
         		p->nextsibling=b->nextsibling;
         		b->nextsibling=NULL;
         		DestroyTree(b);
       		}
       		else // p       i
         		return ERROR;
     	}
     	return OK;
   	}
   	else
     	return ERROR;
}

//       —          T
void PostOrderTraverse(CSTree T,void(*Visit)(TElemType))
{ 
   	CSTree p;
   	if(T)
   	{
     	if(T->firstchild) //    
     	{
       		PostOrderTraverse(T->firstchild,Visit); //         
       		p=T->firstchild->nextsibling; // p          
       		while(p)
       		{
         		PostOrderTraverse(p,Visit); //            
         		p=p->nextsibling; // p        
       		}
     	}
     	Visit(Value(T)); //        
   	}
}

//       —          T
void LevelOrderTraverse(CSTree T,void(*Visit)(TElemType))
{ 
   	CSTree p;
   	LinkQueue q;
   	InitQueue(q);
   	if(T)
   	{
     	Visit(Value(T)); //       
     	EnQueue(q,T); //         
     	while(!QueueEmpty(q)) //    
     	{
       		DeQueue(q,p); //          
       		if(p->firstchild) //    
       		{
         		p=p->firstchild;
         		Visit(Value(p)); //       
         		EnQueue(q,p); //          
         		while(p->nextsibling) //       
         		{
           			p=p->nextsibling;
           			Visit(Value(p)); //        
           			EnQueue(q,p); //          
         		}
       		}
     	}
   	}
}

void vi(TElemType c)
{
   	printf("%c ",c);
}

int main()
{
   int i;
   CSTree T,p,q;
   TElemType e,e1;
   InitTree(T);
   printf("     ,   ? %d(1:  0: )    %c      %d
",TreeEmpty(T),Root(T),TreeDepth(T)); CreateTree(T); printf(" T , ? %d(1: 0: ) %c %d
",TreeEmpty(T),Root(T),TreeDepth(T)); printf(" T:
"); PreOrderTraverse(T,vi); printf("
: "); scanf("%c%*c%c%*c",&e,&e1); Assign(T,e,e1); printf(" T:
"); PostOrderTraverse(T,vi); printf("
%c %c, %c, %c
",e1,Parent(T,e1),LeftChild(T,e1),RightSibling(T,e1)); printf(" p:
"); InitTree(p); CreateTree(p); printf(" p:
"); LevelOrderTraverse(p,vi); printf("
p T , T p : "); scanf("%c%d%*c",&e,&i); q=Point(T,e); InsertChild(T,q,i,p); printf(" T:
"); LevelOrderTraverse(T,vi); printf("
T e i , e i: "); scanf("%c%d",&e,&i); q=Point(T,e); DeleteChild(T,q,i); printf(" T:
",e,i); LevelOrderTraverse(T,vi); printf("
"); DestroyTree(T); }