樹的創建與數據打印

//頭文件 TREE.h

#ifndef _TREE_H_
#define _TREE_H_

#define false 0
#define true 1
typedef _TreeNode;

typedef struct _ChildNode  //孩子結點型鏈表
{
	struct _TreeNode *childNode; //孩子結點指向父結點的指針
	struct _ChildNode *next; //指向孩子結點鏈表下一個元素

}ChildNode;

typedef char TreeData;  //樹結點類型
typedef struct _TreeNode
{
	TreeData data;
	struct _TreeNode *parent; //指向父結點的指針
	struct _TreeNode *next;  //指向鏈表的下一個元素
	struct _ChildNode *childlist;  //父結點指向孩子鏈表的頭結點
	int degree;//結點的度(後繼的數量)
}TreeNode;

typedef struct _Tree
{
	struct _TreeNode *head;   //樹鏈表的頭結點
	int len;   //樹結點的個數(長度)
}Tree;
//定義一個函數指針類型
typedef void (*TreePrint)(TreeNode *node);

Tree *Create_Tree();
//pos 要插入父結點
int Insert_Tree(Tree *tree,TreeData data,int pos);

void Display (Tree *tree,TreePrint pFunc);
#endif   //_TREE_H_


//函數源代碼 TREE.c
#include "tree.h"

#include <stdlib.h>


Tree *Create_Tree()
{	
    //創建樹結點
	Tree *tree = (Tree *)malloc(sizeof(Tree) / sizeof(char));
	if(tree == NULL)
	{
		return false;
	}
	
	//創建樹結點鏈表的頭結點
	tree->head = (TreeNode *)malloc(sizeof(TreeNode) / sizeof(char));
	if(tree->head == NULL)
	{
		free(tree);
		return NULL;
	}
	//給元素賦值 
	tree->head->parent    = NULL;
	tree->head->next      = NULL;
	tree->head->childlist = NULL;//置空,樹中沒有結點
	
	tree->len = 0;
	
	return tree;
}


// pos 代表要插入結點父親結點的位置
int Insert_Tree(Tree *tree,TreeData data,int pos)
{
	if(tree == NULL || pos < 0 || pos > tree->len)
	{
		return false;
	}
	
	if(pos != 0 && tree->len == pos)
	{
		return false;
	}
	
	//新建結點
	TreeNode *node = (TreeNode *)malloc(sizeof(TreeNode) / sizeof(char));
	if(node == NULL)
	{
		return false;
	}
	
	node->data = data;
	node->next = NULL;
	
	//創建node結點的孩子結點鏈表的頭結點
	node->childlist = (ChildNode *)malloc(sizeof(ChildNode) / sizeof(char));
	if(node->childlist == NULL)
	{
		free(node);
		return false;
	}
	
	node->childlist->next      = NULL;
	node->childlist->childNode = NULL;
	node->degree = 0;
	
	//找父結點
	int i;
	TreeNode *parent = tree->head->next;  //樹結點的第一個結點,根節點
	for(i = 0;i < pos;i++)
	{
		parent = parent->next;
	}
		node->parent = parent;
	
	if(parent != NULL)
	{    //在孩子鏈表中創建一個結點
		ChildNode *childnode = (ChildNode *)malloc(sizeof(ChildNode) / sizeof(char));
		if(childnode == NULL)
		{
			free(node->childlist);
			free(node);
			return false;
		}
		childnode->childNode = node;
		childnode->next = NULL;
		
		//把childnode加入到父結點node的孩子鏈表中
		ChildNode *tmp = parent->childlist;//孩子鏈表的頭結點
		while(tmp->next)
			tmp = tmp->next;
		
		tmp->next = childnode;
		parent->degree += 1;//後繼(度)加一
		
	}
	
	TreeNode *tmp = tree->head;//樹結點鏈表的頭結點
		while(tmp->next)
			tmp = tmp->next;
		
		tmp->next = node;
		tree->len += 1;
		
		return true;
	
}


void R_Display(TreeNode *node,int gap,TreePrint pFunc)  //遞歸打印結點
{
	if(node == NULL)
		return;
	
	//打印距離前一個結點的距離
	int i;
	for(i = 0;i < gap;i++)
	{
		printf("%c",'-');
	}
	//打印結點自己
	pFunc(node);
	
	ChildNode *child = node->childlist->next;//該節點的第一個孩子結點
	//用遞歸打印結點孩子
		while(child)
		{
			R_Display (child->childNode,gap+4,pFunc);
			child = child->next;
		}
}

void Display(Tree *tree,TreePrint pFunc)//打印樹
{
	if(tree == NULL)
		return;
		
	R_Display(tree->head->next,0,pFunc);//先打印根節點
}


//主函數 mani.c
#include <stdio.h>
#include "tree.h"

void printA(TreeNode *node)
{
	printf("%c\n",node->data);
}


int main()
{
	Tree *tree = Create_Tree();
	if(tree == NULL)
	{
		return -1;
	}
	
	Insert_Tree(tree,'A',0);
	Insert_Tree(tree,'B',0);
	Insert_Tree(tree,'C',0);
	Insert_Tree(tree,'D',0);
	Insert_Tree(tree,'E',1);
	Insert_Tree(tree,'F',1);
	Insert_Tree(tree,'H',3);
	Insert_Tree(tree,'I',3);

	
	Display(tree,printA);
	
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章