数据结构-树的存储结构
来源:互联网 发布:linux打开oracle服务 编辑:程序博客网 时间:2024/04/30 03:56
树的存储结构:
利用链表组织树中的各个结点
链表中的前后关系不代表结点间的逻辑关系
结点的逻辑关系由 child 数据域描述
child 数据域保存其他结点的存储地址
树结点结构体
typedef struct _tag_GTreeNode GTreeNode;struct _tag_GTreeNode{ GTreeData* data; GTreeNode* parent; LinkList* child;};链表结点结构体
typedef struct _tag_LinkList{ LinkListNode header; int length;} TLinkList;
树结点在链表中的位置不代表树的任何逻辑关系。
下面给出代码:
首先是线性表的头文件LinkList.h
#ifndef _LINKLIST_H_#define _LINKLIST_H_typedef void LinkList;typedef struct _tag_LinkListNode LinkListNode;struct _tag_LinkListNode{ LinkListNode* next;};LinkList* LinkList_Create();void LinkList_Destroy(LinkList* list);void LinkList_Clear(LinkList* list);int LinkList_Length(LinkList* list);int LinkList_Insert(LinkList* list, LinkListNode* node, int pos);LinkListNode* LinkList_Get(LinkList* list, int pos);LinkListNode* LinkList_Delete(LinkList* list, int pos);#endif线性表的实现文件LinkList.c
#include <stdio.h>#include <malloc.h>#include "LinkList.h"typedef struct _tag_LinkList{ LinkListNode header; int length;} TLinkList;LinkList* LinkList_Create() // O(1){ TLinkList* ret = (TLinkList*)malloc(sizeof(TLinkList)); if( ret != NULL ) { ret->length = 0; ret->header.next = NULL; } return ret;}void LinkList_Destroy(LinkList* list) // O(1){ free(list);}void LinkList_Clear(LinkList* list) // O(1){ TLinkList* sList = (TLinkList*)list; if( sList != NULL ) { sList->length = 0; sList->header.next = NULL; }}int LinkList_Length(LinkList* list) // O(1){ TLinkList* sList = (TLinkList*)list; int ret = -1; if( sList != NULL ) { ret = sList->length; } return ret;}int LinkList_Insert(LinkList* list, LinkListNode* node, int pos) // O(n){ TLinkList* sList = (TLinkList*)list; int ret = (sList != NULL) && (pos >= 0) && (node != NULL); int i = 0; if( ret ) { LinkListNode* current = (LinkListNode*)sList; for(i=0; (i<pos) && (current->next != NULL); i++) { current = current->next; } node->next = current->next; current->next = node; sList->length++; } return ret;}LinkListNode* LinkList_Get(LinkList* list, int pos) // O(n){ TLinkList* sList = (TLinkList*)list; LinkListNode* ret = NULL; int i = 0; if( (sList != NULL) && (0 <= pos) && (pos < sList->length) ) { LinkListNode* current = (LinkListNode*)sList; for(i=0; i<pos; i++) { current = current->next; } ret = current->next; } return ret;}LinkListNode* LinkList_Delete(LinkList* list, int pos) // O(n){ TLinkList* sList = (TLinkList*)list; LinkListNode* ret = NULL; int i = 0; if( (sList != NULL) && (0 <= pos) && (pos < sList->length) ) { LinkListNode* current = (LinkListNode*)sList; for(i=0; i<pos; i++) { current = current->next; } ret = current->next; current->next = ret->next; sList->length--; } return ret;}树定义头文件GTree.h
#ifndef _TREE_H_#define _TREE_H_typedef void Tree;typedef void TreeNode;/* 创建树 */Tree* Tree_Create();/* 销毁已存在的树 */void Tree_Destroy(Tree* tree);/* 将已存在的树清空为空树 */void Tree_Clear(Tree* tree);/* 将结点node插入到tree中的pos位置处 */int Tree_Insert(Tree* tree, TreeNode* node, int pos);/* 将tree中pos位置的结点删除并返回 */TreeNode* Tree_Delete(Tree* tree, int pos);/* 将tree中pos位置的结点返回 */TreeNode* Tree_Get(Tree* tree, int pos);/* 返回tree的根结点 */TreeNode* Tree_Root(Tree* tree);/* 返回tree的高度 */int Tree_Height(Tree* tree);/* 返回树的结点数 */int Tree_Count(Tree* tree);/* 返回树的度数 */int Tree_Degree(Tree* tree);#endif树实现文件GTree.c
#include <stdio.h>#include <malloc.h>#include "GTree.h"#include "LinkList.h"typedef struct _tag_GTreeNode GTreeNode;struct _tag_GTreeNode{ GTreeData* data; GTreeNode* parent; LinkList* child;};typedef struct _tag_TLNode TLNode;struct _tag_TLNode{ LinkListNode header; GTreeNode* node;};static void recursive_display(GTreeNode* node, GTree_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->data); printf("\n"); for(i=0; i<LinkList_Length(node->child); i++) { TLNode* trNode = (TLNode*)LinkList_Get(node->child, i); recursive_display(trNode->node, pFunc, format + gap, gap, div); } }}static void recursive_delete(LinkList* list, GTreeNode* node){ if( (list != NULL) && (node != NULL) ) { GTreeNode* parent = node->parent; int index = -1; int i = 0; for(i=0; i<LinkList_Length(list); i++) { TLNode* trNode = (TLNode*)LinkList_Get(list, i); if( trNode->node == node ) { LinkList_Delete(list, i); free(trNode); index = i; break; } } if( index >= 0 ) { if( parent != NULL ) { for(i=0; i<LinkList_Length(parent->child); i++) { TLNode* trNode = (TLNode*)LinkList_Get(parent->child, i); if( trNode->node == node ) { LinkList_Delete(parent->child, i); free(trNode); break; } } } while( LinkList_Length(node->child) > 0 ) { TLNode* trNode = (TLNode*)LinkList_Get(node->child, 0); recursive_delete(list, trNode->node); } LinkList_Destroy(node->child); free(node); } }}static int recursive_height(GTreeNode* node){ int ret = 0; if( node != NULL ) { int subHeight = 0; int i = 0; for(i=0; i<LinkList_Length(node->child); i++) { TLNode* trNode = (TLNode*)LinkList_Get(node->child, i); subHeight = recursive_height(trNode->node); if( ret < subHeight ) { ret = subHeight; } } ret = ret + 1; } return ret;}static int recursive_degree(GTreeNode* node){int ret = -1; if( node != NULL ) { int subDegree = 0; int i = 0; ret = LinkList_Length(node->child); for(i=0; i<LinkList_Length(node->child); i++) { TLNode* trNode = (TLNode*)LinkList_Get(node->child, i); subDegree = recursive_degree(trNode->node); if( ret < subDegree ) { ret = subDegree; } } } return ret;}GTree* GTree_Create(){ return LinkList_Create();}void GTree_Destroy(GTree* tree){ GTree_Clear(tree); LinkList_Destroy(tree);}void GTree_Clear(GTree* tree){ GTree_Delete(tree, 0);}int GTree_Insert(GTree* tree, GTreeData* data, int pPos){ LinkList* list = (LinkList*)tree; int ret = (list != NULL) && (data != NULL) && (pPos < LinkList_Length(list)); if( ret ) { TLNode* trNode = (TLNode*)malloc(sizeof(TLNode)); TLNode* cldNode = (TLNode*)malloc(sizeof(TLNode)); TLNode* pNode = (TLNode*)LinkList_Get(list, pPos); GTreeNode* cNode = (GTreeNode*)malloc(sizeof(GTreeNode)); ret = (trNode != NULL) && (cldNode != NULL) && (cNode != NULL); if( ret ) { cNode->data = data; cNode->parent = NULL; cNode->child = LinkList_Create(); trNode->node = cNode; cldNode->node = cNode; LinkList_Insert(list, (LinkListNode*)trNode, LinkList_Length(list)); if( pNode != NULL ) { cNode->parent = pNode->node; LinkList_Insert(pNode->node->child, (LinkListNode*)cldNode, LinkList_Length(pNode->node->child)); } } else { free(trNode); free(cldNode); free(cNode); } } return ret;}GTreeData* GTree_Delete(GTree* tree, int pos){ TLNode* trNode = (TLNode*)LinkList_Get(tree, pos); GTreeData* ret = NULL; if( trNode != NULL ) { ret = trNode->node->data; recursive_delete(tree, trNode->node); } return ret;}GTreeData* GTree_Get(GTree* tree, int pos){ TLNode* trNode = (TLNode*)LinkList_Get(tree, pos); GTreeData* ret = NULL; if( trNode != NULL ) { ret = trNode->node->data; } return ret;}GTreeData* GTree_Root(GTree* tree){ return GTree_Get(tree, 0);}int GTree_Height(GTree* tree){ TLNode* trNode = (TLNode*)LinkList_Get(tree, 0); int ret = 0; if( trNode != NULL ) { ret = recursive_height(trNode->node); } return ret;}int GTree_Count(GTree* tree){ return LinkList_Length(tree);}int GTree_Degree(GTree* tree){ TLNode* trNode = (TLNode*)LinkList_Get(tree, 0); int ret = -1; if( trNode != NULL ) { ret = recursive_degree(trNode->node); } return ret;}void GTree_Display(GTree* tree, GTree_Printf* pFunc, int gap, char div){ TLNode* trNode = (TLNode*)LinkList_Get(tree, 0); if( (trNode != NULL) && (pFunc != NULL) ) { recursive_display(trNode->node, pFunc, 0, gap, div); }}测试文件main.c
#include <stdio.h>#include "GTree.h"/* run this program using the console pauser or add your own getch, system("pause") or input loop */void printf_data(GTreeData* data){ printf("%c", (int)data);}int main(int argc, char *argv[]){ GTree* tree = GTree_Create(); int i = 0; GTree_Insert(tree, (GTreeData*)'A', -1); GTree_Insert(tree, (GTreeData*)'B', 0); GTree_Insert(tree, (GTreeData*)'C', 0); GTree_Insert(tree, (GTreeData*)'D', 0); GTree_Insert(tree, (GTreeData*)'E', 1); GTree_Insert(tree, (GTreeData*)'F', 1); GTree_Insert(tree, (GTreeData*)'H', 3); GTree_Insert(tree, (GTreeData*)'I', 3); GTree_Insert(tree, (GTreeData*)'J', 3); printf("Tree Height: %d\n", GTree_Height(tree)); printf("Tree Degree: %d\n", GTree_Degree(tree)); printf("Full Tree:\n"); GTree_Display(tree, printf_data, 2, ' '); printf("Get Tree Data:\n"); for(i=0; i<GTree_Count(tree); i++) { printf_data(GTree_Get(tree, i)); printf("\n"); } printf("Get Root Data:\n"); printf_data(GTree_Root(tree)); printf("\n"); GTree_Delete(tree, 3); printf("After Deleting D:\n"); GTree_Display(tree, printf_data, 2, '-'); GTree_Clear(tree); printf("After Clearing Tree:\n"); GTree_Display(tree, printf_data, 2, '.'); GTree_Destroy(tree); return 0;}运行结果:
总结:
本篇中的树结构是一种通用的数据结构
利用链表组织树结点
能够便利的存取结点
链表的维护具有一定复杂性
0 0
- 数据结构-树的存储结构
- 数据结构 树及树的存储结构
- 数据结构——树的存储结构
- 数据结构 - 二叉树的存储结构
- 数据结构(7):树的存储结构
- 数据结构(8):二叉树的存储结构
- 数据结构之树的存储结构
- 树的存储结构(数据结构)
- 二叉树的存储结构(数据结构)
- 数据结构---->图的存储结构
- 数据结构的链式存储结构
- 数据结构 - 图的存储结构
- 数据结构:串的存储结构
- 数据结构---图的存储结构
- 数据结构的顺序存储结构
- 数据结构的链式存储结构
- 【数据结构】图的存储结构
- 【数据结构】二叉树的顺序存储结构--遍历二叉树
- 浩爷AC自动机快速学习方案
- mac git+shell实现快速提交push
- 嵌入式工程师考试知识点总结 微内核结构
- 断其一指------Service的使用
- UVa 1587 - Box
- 数据结构-树的存储结构
- Linux内核--内核地址空间分布和进程地址空间
- OC菜鸟成长记-OC常用数据类型
- maven学习笔记(windows)一
- 斐波拉契数列
- 多线程访问共享数据的安全问题
- WPF中播放帧序列图
- Java中的wait()方法和sleep()方法的区别是什么?
- Vanya and Books