【数据结构笔记】树

树的定义

 

 

树操作的实现

文件树

树的存储结构

 

GTree.h

 

 
  1. <strong><span style="font-size:18px;">#ifndef _GTREE_H_

  2. #define _GTREE_H_

  3.  
  4. typedef void GTree;

  5. typedef void GTreeData;

  6. typedef void (GTree_Printf)(GTreeData*);

  7.  
  8. GTree* GTree_Create();

  9.  
  10. void GTree_Destroy(GTree* tree);

  11.  
  12. void GTree_Clear(GTree* tree);

  13.  
  14. int GTree_Insert(GTree* tree, GTreeData* data, int pPos);

  15.  
  16. GTreeData* GTree_Delete(GTree* tree, int pos);

  17.  
  18. GTreeData* GTree_Get(GTree* tree, int pos);

  19.  
  20. GTreeData* GTree_Root(GTree* tree);

  21.  
  22. int GTree_Height(GTree* tree);

  23.  
  24. int GTree_Count(GTree* tree);

  25.  
  26. int GTree_Degree(GTree* tree);

  27.  
  28. void GTree_Display(GTree* tree, GTree_Printf* pFunc, int gap, char div);

  29.  
  30. #endif

  31. </span></strong>


 

 

 

GTree.c

 

 
  1. <strong><span style="font-size:18px;">#include <stdio.h>

  2. #include <malloc.h>

  3. #include "GTree.h"

  4. #include "LinkList.h"

  5.  
  6.  
  7. typedef struct _tag_GTreeNode GTreeNode;

  8. struct _tag_GTreeNode

  9. {

  10. GTreeData* data;

  11. GTreeNode* parent;

  12. LinkList* child;

  13. };

  14.  
  15.  
  16. typedef struct _tag_TLNode TLNode;

  17. struct _tag_TLNode

  18. {

  19. LinkListNode header;

  20. GTreeNode* node;

  21. };

  22.  
  23.  
  24. static void recursive_display(GTreeNode* node, GTree_Printf* pFunc, int format, int gap, char div)

  25. { //数据

  26. int i = 0;

  27.  
  28. if( (node != NULL) && (pFunc != NULL) )

  29. {

  30. for(i=0; i<format; i++)

  31. {

  32. printf("%c", div);

  33. } //符号

  34.  
  35. pFunc(node->data);

  36.  
  37. printf("\n");

  38.  
  39. for(i=0; i<LinkList_Length(node->child); i++)

  40. {

  41. TLNode* trNode = (TLNode*)LinkList_Get(node->child, i);

  42.  
  43. recursive_display(trNode->node, pFunc, format + gap, gap, div);

  44. }

  45. }

  46. }

  47.  
  48. static void recursive_delete(LinkList* list, GTreeNode* node)

  49. {

  50. if( (list != NULL) && (node != NULL) )

  51. {

  52. GTreeNode* parent = node->parent;

  53. int index = -1;

  54. int i = 0;

  55.  
  56. for(i=0; i<LinkList_Length(list); i++)

  57. {

  58. TLNode* trNode = (TLNode*)LinkList_Get(list, i);

  59.  
  60. if( trNode->node == node )

  61. {

  62. LinkList_Delete(list, i);

  63.  
  64. free(trNode);

  65.  
  66. index = i;

  67.  
  68. break;

  69. }

  70. }

  71.  
  72. if( index >= 0 )//从父结点删除

  73. {

  74. if( parent != NULL )

  75. {

  76. for(i=0; i<LinkList_Length(parent->child); i++)

  77. {

  78. TLNode* trNode = (TLNode*)LinkList_Get(parent->child, i);

  79.  
  80. if( trNode->node == node )

  81. {

  82. LinkList_Delete(parent->child, i);

  83.  
  84. free(trNode);

  85.  
  86. break;

  87. }

  88. }

  89. }

  90.  
  91. while( LinkList_Length(node->child) > 0 )//将孩子们也删掉

  92. {

  93. TLNode* trNode = (TLNode*)LinkList_Get(node->child, 0);

  94.  
  95. recursive_delete(list, trNode->node);

  96. }

  97.  
  98. LinkList_Destroy(node->child);

  99.  
  100. free(node);

  101. }

  102. }

  103. }

  104.  
  105. static int recursive_height(GTreeNode* node)

  106. {

  107. int ret = 0;

  108.  
  109. if( node != NULL )

  110. {

  111. int subHeight = 0;

  112. int i = 0;

  113.  
  114. for(i=0; i<LinkList_Length(node->child); i++)

  115. {

  116. TLNode* trNode = (TLNode*)LinkList_Get(node->child, i);

  117.  
  118. subHeight = recursive_height(trNode->node);

  119.  
  120. if( ret < subHeight )

  121. {

  122. ret = subHeight;

  123. }

  124. }

  125.  
  126. ret = ret + 1;

  127. } //加上根结点

  128.  
  129. return ret;

  130. }

  131.  
  132. static int recursive_degree(GTreeNode* node)

  133. {

  134. int ret = -1;

  135.  
  136. if( node != NULL )

  137. {

  138. int subDegree = 0;

  139. int i = 0;

  140.  
  141. ret = LinkList_Length(node->child);

  142.  
  143. for(i=0; i<LinkList_Length(node->child); i++)

  144. {

  145. TLNode* trNode = (TLNode*)LinkList_Get(node->child, i);

  146.  
  147. subDegree = recursive_degree(trNode->node);

  148.  
  149. if( ret < subDegree )

  150. {

  151. ret = subDegree;

  152. }

  153. }

  154. }

  155.  
  156. return ret;

  157. }

  158.  
  159. GTree* GTree_Create()

  160. {

  161. return LinkList_Create();

  162. }

  163.  
  164. void GTree_Destroy(GTree* tree)

  165. {

  166. GTree_Clear(tree);

  167. LinkList_Destroy(tree);

  168. }

  169.  
  170. void GTree_Clear(GTree* tree)

  171. {

  172. GTree_Delete(tree, 0);

  173. }

  174.  
  175. int GTree_Insert(GTree* tree, GTreeData* data, int pPos)

  176. {

  177. LinkList* list = (LinkList*)tree;

  178. int ret = (list != NULL) && (data != NULL) && (pPos < LinkList_Length(list));

  179.  
  180. if( ret )

  181. {

  182. TLNode* trNode = (TLNode*)malloc(sizeof(TLNode));

  183. TLNode* cldNode = (TLNode*)malloc(sizeof(TLNode));

  184. TLNode* pNode = (TLNode*)LinkList_Get(list, pPos);

  185. GTreeNode* cNode = (GTreeNode*)malloc(sizeof(GTreeNode));

  186.  
  187. ret = (trNode != NULL) && (cldNode != NULL) && (cNode != NULL);

  188.  
  189. if( ret )

  190. {

  191. cNode->data = data;

  192. cNode->parent = NULL;

  193. cNode->child = LinkList_Create();

  194.  
  195. trNode->node = cNode;

  196. cldNode->node = cNode;

  197.  
  198. LinkList_Insert(list, (LinkListNode*)trNode, LinkList_Length(list));

  199.  
  200. if( pNode != NULL )

  201. {

  202. cNode->parent = pNode->node;

  203.  
  204. LinkList_Insert(pNode->node->child, (LinkListNode*)cldNode, LinkList_Length(pNode->node->child));

  205. }

  206. }

  207. else

  208. {

  209. free(trNode);

  210. free(cldNode);

  211. free(cNode);

  212. }

  213. }

  214.  
  215. return ret;

  216. }

  217.  
  218. GTreeData* GTree_Delete(GTree* tree, int pos)

  219. {

  220. TLNode* trNode = (TLNode*)LinkList_Get(tree, pos);

  221. GTreeData* ret = NULL;

  222.  
  223. if( trNode != NULL )

  224. {

  225. ret = trNode->node->data;

  226.  
  227. recursive_delete(tree, trNode->node);

  228. }

  229.  
  230. return ret;

  231. }

  232.  
  233. GTreeData* GTree_Get(GTree* tree, int pos)

  234. {

  235. TLNode* trNode = (TLNode*)LinkList_Get(tree, pos);

  236. GTreeData* ret = NULL;

  237.  
  238. if( trNode != NULL )

  239. {

  240. ret = trNode->node->data;

  241. }

  242.  
  243. return ret;

  244. }

  245.  
  246. GTreeData* GTree_Root(GTree* tree)

  247. {

  248. return GTree_Get(tree, 0);

  249. }

  250.  
  251. int GTree_Height(GTree* tree)

  252. {

  253. TLNode* trNode = (TLNode*)LinkList_Get(tree, 0);

  254. int ret = 0;

  255.  
  256. if( trNode != NULL )

  257. {

  258. ret = recursive_height(trNode->node);

  259. }

  260.  
  261. return ret;

  262. }

  263.  
  264. int GTree_Count(GTree* tree)

  265. {

  266. return LinkList_Length(tree);

  267. }

  268.  
  269. int GTree_Degree(GTree* tree)

  270. {

  271. TLNode* trNode = (TLNode*)LinkList_Get(tree, 0);

  272. int ret = -1;

  273.  
  274. if( trNode != NULL )

  275. {

  276. ret = recursive_degree(trNode->node);

  277. }

  278.  
  279. return ret;

  280. }

  281.  
  282. void GTree_Display(GTree* tree, GTree_Printf* pFunc, int gap, char div)

  283. {

  284. TLNode* trNode = (TLNode*)LinkList_Get(tree, 0);

  285.  
  286. if( (trNode != NULL) && (pFunc != NULL) )

  287. {

  288. recursive_display(trNode->node, pFunc, 0, gap, div);

  289. }

  290. }

  291. </span></strong>


main.c

 

 

 
  1. <strong><span style="font-size:18px;">#include <stdio.h>

  2. #include "GTree.h"

  3. /* run this program using the console pauser or add your own getch, system("pause") or input loop */

  4.  
  5. void printf_data(GTreeData* data)

  6. {

  7. printf("%c", (int)data);

  8. }

  9.  
  10. int main(int argc, char *argv[])

  11. {

  12. GTree* tree = GTree_Create();

  13. int i = 0;

  14.  
  15. GTree_Insert(tree, (GTreeData*)'A', -1);

  16. GTree_Insert(tree, (GTreeData*)'B', 0);

  17. GTree_Insert(tree, (GTreeData*)'C', 0);

  18. GTree_Insert(tree, (GTreeData*)'D', 0);

  19. GTree_Insert(tree, (GTreeData*)'E', 1);

  20. GTree_Insert(tree, (GTreeData*)'F', 1);

  21. GTree_Insert(tree, (GTreeData*)'H', 3);

  22. GTree_Insert(tree, (GTreeData*)'I', 3);

  23. GTree_Insert(tree, (GTreeData*)'J', 3);

  24.  
  25. printf("Tree Height: %d\n", GTree_Height(tree));

  26. printf("Tree Degree: %d\n", GTree_Degree(tree));

  27. printf("Full Tree:\n");

  28.  
  29. GTree_Display(tree, printf_data, 2, ' ');

  30.  
  31. printf("Get Tree Data:\n");

  32.  
  33. for(i=0; i<GTree_Count(tree); i++)

  34. {

  35. printf_data(GTree_Get(tree, i));

  36. printf("\n");

  37. }

  38.  
  39. printf("Get Root Data:\n");

  40.  
  41. printf_data(GTree_Root(tree));

  42.  
  43. printf("\n");

  44.  
  45. GTree_Delete(tree, 3);

  46.  
  47. printf("After Deleting D:\n");

  48.  
  49. GTree_Display(tree, printf_data, 2, '-');

  50.  
  51. GTree_Clear(tree);

  52.  
  53. printf("After Clearing Tree:\n");

  54.  
  55. GTree_Display(tree, printf_data, 2, '.');

  56.  
  57. GTree_Destroy(tree);

  58.  
  59. return 0;

  60. }</span></strong>


 

 

 

 

小结

 

 

二叉树定义

另一种树结构模型

孩子兄弟表示法

实现较简单

 

小结

思考:

 

 

二叉树的深层性质

 

小结

理解和掌握二叉树的深层次特性有助于我们设计出更加精巧高效的算法

 

创建二叉树

指路法定位结点

二叉树存储结构

二叉树的操作

二叉树结构的实现

main.c

#include <stdio.h>
#include <stdlib.h>
#include "BTree.h"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

struct Node{
	BTreeNode header;
	char V;
};

void printf_data(BTreeNode* node)
{
	if(node != NULL)
	{
		printf("%c",((struct Node*)node)->V);	
	}
}

int main(int argc, char *argv[]) {
	
	BTree* tree = BTree_Create();
	
	struct Node n1 = {(NULL),(NULL),'A'};
	struct Node n2 = {(NULL),(NULL),'B'};
	struct Node n3 = {(NULL),(NULL),'C'};
	struct Node n4 = {(NULL),(NULL),'D'};
	struct Node n5 = {(NULL),(NULL),'E'};
	struct Node n6 = {(NULL),(NULL),'F'};
	
	BTree_Insert(tree,(BTreeNode*)&n1,0,0,0);
	BTree_Insert(tree,(BTreeNode*)&n2,0x00,1,0);
	BTree_Insert(tree,(BTreeNode*)&n3,0x01,1,0);
	BTree_Insert(tree,(BTreeNode*)&n4,0x00,2,0);
	BTree_Insert(tree,(BTreeNode*)&n5,0x02,2,0);
	BTree_Insert(tree,(BTreeNode*)&n6,0x02,3,0);
	
	
	printf("Height: %d\n",BTree_Height(tree));
	printf("Degree: %d\n", BTree_Degree(tree));
	printf("count: %d\n",BTree_Count(tree));
	printf("Position at(0x02,2):%c\n",((struct Node*)BTree_Get(tree,0x02,2))->V);
	printf("full tree: \n");
	BTree_Display(tree,printf_data,4,'-');
	
	BTree_Delete(tree,0x00,1);
	printf("fater delete B:\n");
	printf("Height: %d\n",BTree_Height(tree));
	printf("Degree: %d\n", BTree_Degree(tree));
	printf("count: %d\n",BTree_Count(tree));
	printf("full tree: \n");
	
	BTree_Display(tree,printf_data,4,'-');
	BTree_Destroy(tree);
	return 0;
}

BTree.c

#include <stdio.h>
#include <malloc.h>
#include "BTree.h"

//头结点结构体
typedef struct _tag_BTree TBTree;
struct _tag_BTree
{
	int count;
	BTreeNode * root;
};

static void recursive_display(BTreeNode * node,BTree_Printf* pFunc,int format,int gap,char div)
{
	int i = 0;
	
	if((node != NULL) &&(pFunc != NULL))
	{
		for	(i = 0;i<format;i++)
		{
			printf("%c",div);	
		}
		pFunc(node);
		
		printf("\n");
		
		if((node->left != NULL)||(node->right != NULL))
		{
			recursive_display(node->left,pFunc,format + gap,gap,div);
			recursive_display(node->right,pFunc,format + gap,gap,div);
		}
	}
	else 
	{
		for	(i = 0;i<format;i++)
		{
			printf("%c",div);	
		}
		printf("\n");
	}
}

static int recursive_count(BTreeNode* root)
{
	int ret = 0;
	if(root != NULL)
	{
		ret = recursive_count(root->left) +1 +recursive_count(root->right);
	}
	return ret;
}
 
static int recursive_height(BTreeNode* root)
{
	int ret = 0;
	
	if(root != NULL)
	{ 	
		int lh = recursive_height(root->left);
		int rh = recursive_height(root->right);	
		
		ret = ((lh > rh)?lh:rh) + 1;	
	}
	
	return ret;
} 
static int recursive_Degree(BTreeNode* root)
{
	int ret = 0;
	
	if(root != NULL)
	{ 	
		if(root->left != NULL)
		{
			ret++;	
		}	
		if(root->right != NULL)
		{
			ret++;	
		}
		if(ret == 1)
		{
			int ld = recursive_Degree(root->left);
			int rd = recursive_Degree(root->right); 
			
			if(ret < ld)
			{
				ret = ld;	
			}
			if(ret < rd)
			{
				ret = rd;	
			}
		}
	}
	
	return ret;
}
BTree* BTree_Create()
{
	TBTree * ret = (TBTree*)malloc(sizeof(TBTree));
	
	if (ret != NULL)
	{
		ret->count = 0;	//没有节点
		ret->root = NULL; 
	}
	return ret;
}

void BTree_Destroy(BTree* tree)
{
	free(tree);
}

void BTree_Clear(BTree* tree)
{
	TBTree *btree = (TBTree*)tree;
	if(btree != NULL)
	{
		btree->count = 0;
		btree->root = NULL;	
	}
}

int BTree_Insert(BTree* tree, BTreeNode* node, BTPos pos,int count,int flag)
{
	TBTree *btree = (TBTree*)tree;
	int ret = ((btree != NULL) && (node != NULL)&&((flag == BT_LEFT)||(flag == BT_RIGH)));
	int bit = 0;
	
	if (ret)
	{
		BTreeNode * parent = NULL;
		BTreeNode * current = btree->root;
		
		node->left = NULL;
		node->right = NULL;
		while((count > 0) && (current != NULL))
		{
			bit = pos & 1;
			pos = pos >> 1;

			parent = current;
			if(bit == BT_LEFT)
			{
				current = current->left;
			}
			else if(bit == BT_RIGH)
			{
				current = current->right;
			}
			count--;
		}	
		if(flag == BT_LEFT)
		{
			node->left = current;
		}
		else if(flag == BT_RIGH)
		{
			node->right = current;
		}
		
		if(parent != NULL)
		{
			if (bit == BT_LEFT)
			{
				parent->left = node;	
			}
			else if(bit == BT_RIGH)
			{
				parent->right = node;	
			}
		}
		else
		{
			btree->root = node;
		}
		btree->count++;
	}
	
	return ret;
}

BTreeNode* BTree_Delete(BTree* tree, BTPos pos,int count)
{
	TBTree *btree = (TBTree*)tree;
	BTreeNode* ret = NULL;
	int bit = 0;

	if(btree != NULL)
	{
		BTreeNode * parent = NULL;
		BTreeNode * current = btree->root;
		
		while((count > 0) && (current != NULL))
		{
			bit = pos & 1;
			pos = pos >> 1;

			parent = current;
			
			if(bit == BT_LEFT)
			{
				current = current->left;
			}
			else if(bit == BT_RIGH)
			{
				current = current->right;
			}
			count--;
		}
		if(parent != NULL)
		{
			if (bit == BT_LEFT)
			{
				parent->left = NULL;	
			}
			else if(bit == BT_RIGH)
			{
				parent->right = NULL;	
			}
		}
		else
		{
			btree->root = NULL;
		}
		ret = current;
		
		btree->count = btree->count - recursive_count(ret);
	} 
	return ret;
}

BTreeNode* BTree_Get(BTree* tree, int pos,int count)
{
	TBTree *btree = (TBTree*)tree;
	BTreeNode* ret = NULL;
	int bit = 0;

	if(btree != NULL)
	{
		BTreeNode * current = btree->root;
		
		while((count > 0) && (current != NULL))
		{
			bit = pos & 1;
			pos = pos >> 1;
			
			if(bit == BT_LEFT)
			{
				current = current->left;
			}
			else if(bit == BT_RIGH)
			{
				current = current->right;
			}
			count--;
		}
		ret = current;
	} 
	
	return ret;
} 

BTreeNode* BTree_Root(BTree* tree)
{
	TBTree* btree = (TBTree*)tree;
	BTreeNode* ret = NULL;
	
	if(btree != NULL)
	{
		ret = btree->root;	
	}
	return ret;
}

int BTree_Height(BTree* tree)
{
	TBTree* btree = (TBTree*)tree;
	int ret = 0;
	
	if(btree != NULL)
	{
		ret = recursive_height(btree->root);	
	}
	return ret;
}

int BTree_Count(BTree* tree)
{
	TBTree* btree = (TBTree*)tree;
	int ret = 0;
	
	if(btree != NULL)
	{
		ret = btree->count;	
	}
	return ret;
}

int BTree_Degree(BTree* tree)
{
	TBTree* btree = (TBTree*)tree;
	int ret = 0;
	
	if(btree != NULL)
	{
		ret = recursive_Degree(btree->root);	
	}
	return ret;
}

void BTree_Display(BTree* tree, BTree_Printf* pFunc, int gap, char div)
{
	TBTree* btree = (TBTree*)tree;
	
	if(btree != NULL)
	{
		recursive_display(btree->root,pFunc,0,gap,div);	
	}		
} 

BTree.h

#ifndef _BTREE_H_
#define _BTREE_H_

#define BT_LEFT 0
#define BT_RIGH 1
typedef void BTree; 
typedef unsigned long long BTPos;
 
//指针域 
typedef struct _tag_BTreeNode BTreeNode;
struct _tag_BTreeNode
{
	BTreeNode* left;
	BTreeNode* right;
}; 

typedef void (BTree_Printf)(BTreeNode*);

BTree* BTree_Create();

void BTree_Destroy(BTree* tree);

void BTree_Clear(BTree* tree);

int BTree_Insert(BTree* tree, BTreeNode* node, BTPos pos,int count,int flag);

BTreeNode* BTree_Delete(BTree* tree, BTPos pos,int count);

BTreeNode* BTree_Get(BTree* tree, int pos,int count);

BTreeNode* BTree_Root(BTree* tree);

int BTree_Height(BTree* tree);

int BTree_Count(BTree* tree);

int BTree_Degree(BTree* tree);

void BTree_Display(BTree* tree,BTree_Printf* pFunc, int gap, char div);

#endif

小结

 

遍历二叉树

前序遍历

中序遍历

后序遍历

层次遍历

代码

main.c

void pre_order_traversal(BTreeNode* root)
{
	if(root != NULL)
	{
		printf("%c, ", ((struct Node*)root)->v);
		pre_order_traversal(root->left);
		pre_order_traversal(root->right);	
	}
}

void middle_order_traversal(BTreeNode* root)
{
	if(root != NULL)
	{
		middle_order_traversal(root->left);
		printf("%c, ", ((struct Node*)root)->v);
		middle_order_traversal(root->right);	
	}
}

void post_order_traversal(BTreeNode* root)
{
	if(root != NULL)
	{
		post_order_traversal(root->left);
		post_order_traversal(root->right);	
		printf("%c, ", ((struct Node*)root)->v);
	}
}
void level_order_traversal(BTreeNode* root)
{
	if (root != NULL)
	{
		LinkQueue* queue = LinkQueue_Create();
		
		if( queue != NULL )
		{
			LinkQueue_Append(queue, root);
			 while( LinkQueue_Length(queue) > 0 )
            {
                struct Node* node = (struct Node*)LinkQueue_Retrieve(queue);
                
                printf("%c, ", node->v);
                
                LinkQueue_Append(queue, node->header.left);
                LinkQueue_Append(queue, node->header.right);
            }
		}	
	}
} 

小结

 

 

线索化二叉树

代码:


void thread_via_left(BTreeNode* root, BTreeNode** pp)
{
    if( (root != NULL) && (pp != NULL) )
    {
        if( *pp != NULL )
        {
            (*pp)->left = root;
            *pp = NULL;
        }
        
        if( root->left == NULL )
        {
            *pp = root;
        }
        
        thread_via_left(root->left, pp);
        thread_via_left(root->right, pp);
    }
}

void thread_via_list(BTreeNode* root, SeqList* list)
{
    if( (root != NULL) && (list != NULL) )
    {
        SeqList_Insert(list, (SeqListNode*)root, SeqList_Length(list));
        
        thread_via_list(root->left, list);
        thread_via_list(root->right, list);
    }
}

main.c

    printf("Thread via List:\n");
    
    list = SeqList_Create(BTree_Count(tree));
    
    thread_via_list(BTree_Root(tree), list);
    
    for(i=0; i<SeqList_Length(list); i++)
    {
        printf("%c, ", ((struct Node*)SeqList_Get(list, i))->v);
    }
    
    printf("\n");
    
    printf("Thread via Left:\n");
    
    current = BTree_Root(tree);
    
    thread_via_left(current, &p);
    
    while( current != NULL )
    {
        printf("%c, ", ((struct Node*)current)->v);
        
        current = current->left;
    }
    
    printf("\n");

 

小结

 

 

 

霍夫曼树

最初的解决方案

存在的问题

另一种编码方式

精妙之处

怎么得到?

霍夫曼树

霍夫曼树的应用

小结

 

思考:

 
  1. <strong><span style="font-size:18px;">1.二叉树定义

  2.  
  3. typedef struct BTreeNodeElement_t_ {

  4. void *data;

  5. } BTreeNodeElement_t;

  6.  
  7.  
  8. typedef struct BTreeNode_t_ {

  9. BTreeNodeElement_t *m_pElemt;

  10. struct BTreeNode_t_ *m_pLeft;

  11. struct BTreeNode_t_ *m_pRight;

  12. } BTreeNode_t;</span></strong>

 

 
  1. <strong><span style="font-size:18px;">2.比较两个二叉树结构和数据是否同时相同,即两个一模一样的树

  2.  
  3. 与上面的不同之处在于:在比较结构是否相同之后,需要比较当前节点的数据是否一致。

  4.  
  5. 算法是一致的,只需要添加一行代码即可。

  6.  
  7. (1)递归方式:

  8.  
  9.  
  10.  
  11. bool BTreeCompare( BTreeNode_t *pRoot1, BTreeNode_t *pRoot2)

  12. {

  13. //如果都为空树,则相同

  14. if( pRoot1 == NULL && pRoot2 == NULL )

  15. return true;

  16. //如果一个为空,一个不为空,则不相同

  17. if( ( pRoot1 != NULL && pRoot2 == NULL ) ||

  18. ( pRoot1 == NULL && pRoot2 != NULL ) )

  19. return false;

  20. //比较当前节点中的数据

  21. if( pRoot1->m_pElemt != pRoot2->m_pElemt)

  22. return false;

  23. //如果都不为空,则 需要比较左右子树后,再根据比较结果断定

  24. bool leftCmp = BTreeCompare( pRoot1->m_pLeft, pRoot2->m_pLeft);

  25. bool rightCmp = BTreeCompare( pRoot1->m_pRight, pRoot2->m_pRight);

  26.  
  27. return ( leftCmp && rightCmp );

  28. }

  29.  
  30. (2)非递归方式

  31.  
  32. bool BTreeCompare(BTreeNode_t *pRoot1, BTreeNode_t *pRoot2)

  33. {

  34. if( pRoot1 == NULL && pRoot2 == NULL )

  35. return false;

  36.  
  37.  
  38. queue <BTreeNode_t *> que1;

  39. queue <BTreeNode_t *> que2;

  40.  
  41.  
  42. que1.push(pRoot1);

  43. que2.push(pRoot2);

  44.  
  45.  
  46. int curLevelNodeTotal1 = 0;

  47. int curLevelNodeTotal2 = 0;

  48.  
  49.  
  50. bool flag = true; //作为比较不一致时跳出标识

  51. while( ( !que1.empty()) && ( !que2.empty())) //当两个队列均不为空时,才进行比较

  52. {

  53. curLevelNodeTotal1 = que1.size(); //获取树1的当前层节点总数

  54. curLevelNodeTotal2 = que2.size(); //获取树2的当前层节点总数

  55. if( curLevelNodeTotal1 != curLevelNodeTotal2){

  56. flag = false;//当前层节点总数都不一致,不需要比较了,直接跳出

  57. break;

  58. }

  59. int cnt1 = 0;//遍历本层节点时的计数器

  60. int cnt2 = 0;

  61. while( cnt1 < curLevelNodeTotal1 && cnt2 < curLevelNodeTotal2){

  62. ++cnt1;

  63. ++cnt2;

  64. pRoot1 = que1.front();

  65. que1.pop();

  66. pRoot2 = que2.front();

  67. que2.pop();

  68.  
  69. //比较当前节点中数据是否一致

  70. if( pRoot1->m_pElemt != pRoot2->m_pElemt ){

  71. flag = false;

  72. break;

  73. }

  74. //判断pRoot1和pRoot2左右节点结构是否相同

  75. if( ( pRoot1->m_pLeft != NULL && pRoot2->m_pLeft == NULL ) ||

  76. ( pRoot1->m_pLeft == NULL && pRoot2->m_pLeft != NULL ) ||

  77. ( pRoot1->m_pRight != NULL && pRoot2->m_pRight == NULL ) ||

  78. ( pRoot1->m_pRight == NULL && pRoot2->m_pRight != NULL )

  79. ){

  80. flag = false;

  81. break;

  82. }

  83.  
  84. //将左右节点入队

  85. if( pRoot1->m_pLeft != NULL )

  86. que1.push( pRoot1->m_pLeft);

  87. if( pRoot1->m_pRight != NULL )

  88. que1.push( pRoot1->m_pRight);

  89. if( pRoot2->m_pLeft != NULL )

  90. que2.push( pRoot2->m_pLeft);

  91. if( pRoot2->m_pRight != NULL )

  92. que2.push( pRoot2->m_pRight);

  93. }

  94.  
  95.  
  96. if( flag == false )

  97. break;

  98. }

  99.  
  100. //如果比较标志为false,则不相同

  101. if( flag == false ){

  102. while( !que1.empty() )

  103. que1.pop();

  104. while( !que2.empty())

  105. que2.pop();

  106.  
  107.  
  108. return false;

  109. }

  110.  
  111.  
  112. return true;

  113. }</span></strong>


 

 

 

树应用编译器的开发和数据库的开发

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值