通用树结构的链式存储
2016-06-29 23:27
337 查看
#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
#include "LinkList.h"#include <malloc.h>#include <stdio.h>typedef struct _tag_LinkList{<span style="white-space:pre"> </span>LinkListNode header;<span style="white-space:pre"> </span>int length;}TLinkList;LinkList* LinkList_Create() //O(1){<span style="white-space:pre"> </span>TLinkList* ret = (TLinkList*)malloc(sizeof(TLinkList));<span style="white-space:pre"> </span> if(ret != NULL) {<span style="white-space:pre"> </span> ret->length = 0;<span style="white-space:pre"> </span>ret->header.next = NULL;<span style="white-space:pre"> </span><span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>return ret;}void LinkList_Destroy(LinkList* list) //O(1){<span style="white-space:pre"> </span>free(list);}void LinkList_Clear(LinkList* list) //O(1){<span style="white-space:pre"> </span>TLinkList* sList = (TLinkList*)list;<span style="white-space:pre"> </span>if(sList != NULL)<span style="white-space:pre"> </span>{<span style="white-space:pre"> </span> sList->length = 0;<span style="white-space:pre"> </span><span style="white-space:pre"> </span> sList->header.next = NULL;<span style="white-space:pre"> </span>}}int LinkList_Length(LinkList* list) //O(1){<span style="white-space:pre"> </span>TLinkList* sList = (TLinkList*)list;<span style="white-space:pre"> </span>int ret = -1;<span style="white-space:pre"> </span>if(sList != NULL)<span style="white-space:pre"> </span>{<span style="white-space:pre"> </span> ret = sList->length;<span style="white-space:pre"> </span><span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>return ret;<span style="white-space:pre"> </span>}int LinkList_Insert(LinkList* list,LinkListNode* node,int pos) //O(N){<span style="white-space:pre"> </span>TLinkList* sList = (TLinkList*)list;<span style="white-space:pre"> </span>int ret = (sList != NULL);<span style="white-space:pre"> </span>int i = 0;<span style="white-space:pre"> </span><span style="white-space:pre"> </span>ret = ret && (pos>=0) && (node != NULL);<span style="white-space:pre"> </span>if(ret)<span style="white-space:pre"> </span>{<span style="white-space:pre"> </span> LinkListNode* current = (LinkListNode*)sList;<span style="white-space:pre"> </span><span style="white-space:pre"> </span>for(i=0;(i<pos)&&(current->next != NULL);i++)<span style="white-space:pre"> </span>{<span style="white-space:pre"> </span>current = current->next;<span style="white-space:pre"> </span><span style="white-space:pre"> </span>}<span style="white-space:pre"> </span><span style="white-space:pre"> </span>node->next = current->next;<span style="white-space:pre"> </span>current->next=node;<span style="white-space:pre"> </span>sList->length++;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span><span style="white-space:pre"> </span><span style="white-space:pre"> </span>return ret;}LinkListNode* LinkList_Get(LinkList* list,int pos) //O(N){<span style="white-space:pre"> </span>TLinkList* sList = (TLinkList*)list;<span style="white-space:pre"> </span>LinkListNode* ret = NULL;<span style="white-space:pre"> </span>int i = 0;<span style="white-space:pre"> </span><span style="white-space:pre"> </span>if((sList != NULL) && (pos>=0) && (pos < sList->length))<span style="white-space:pre"> </span>{<span style="white-space:pre"> </span>LinkListNode* current = (LinkListNode*)sList;<span style="white-space:pre"> </span>for(i=0;i<pos;i++)<span style="white-space:pre"> </span>{<span style="white-space:pre"> </span>current = current->next;<span style="white-space:pre"> </span><span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>ret = current->next;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>return ret;}LinkListNode* LinkList_Delete(LinkList* list,int pos) //O(N){<span style="white-space:pre"> </span>TLinkList* sList = (TLinkList*)list;<span style="white-space:pre"> </span>LinkListNode* ret = NULL;<span style="white-space:pre"> </span>int i = 0;<span style="white-space:pre"> </span><span style="white-space:pre"> </span>if((sList != NULL) && (pos>=0) && (pos < sList->length))<span style="white-space:pre"> </span>{<span style="white-space:pre"> </span>LinkListNode* current = (LinkListNode*)sList;<span style="white-space:pre"> </span>for(i=0;i<pos;i++)<span style="white-space:pre"> </span>{<span style="white-space:pre"> </span>current = current->next;<span style="white-space:pre"> </span><span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>ret = current->next;<span style="white-space:pre"> </span>current->next = ret->next;<span style="white-space:pre"> </span>sList->length--;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>return ret;}/*<span style="white-space:pre"> </span>小结:<span style="white-space:pre"> </span>优点: 无需一次性定制链表的容量<span style="white-space:pre"> </span>插入和删除操作无需移动数据元素<span style="white-space:pre"> </span><span style="white-space:pre"> </span>缺点:数据元素必须 保存后继元素的位置信息<span style="white-space:pre"> </span>获取指定数据的元素操作需要顺序访问之前的元素。 */#ifndef _GTREE_H_#define _GTREE_H_typedef void GTree;typedef void GTreeData;typedef void (GTree_Printf)(GTreeData*);GTree* GTree_Create();void GTree_Destroy(GTree* tree);void GTree_Clear(GTree* tree);int GTree_Insert(GTree* tree,GTreeData* data,int pPos);GTreeData* GTree_Delete(GTree* tree,int pPos);GTreeData* GTree_Get(GTree* tree,int pPos);GTreeData* GTree_Root(GTree* tree);int GTree_Height(GTree* tree);int GTree_Count(GTree* tree);void GTree_Display(GTree* tree,GTree_Printf* pFunc,char div,int gap);#endif
#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,char div,int gap){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,div,gap);}}}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 = 1;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 = 0;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();}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_Degree(GTree* tree){TLNode* trNode = (TLNode*)LinkList_Get(tree,0);int ret = 0;if(trNode != NULL){ret = recursive_degree(trNode->node);}return ret;}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){GTreeNode* cNode = (GTreeNode*)malloc(sizeof(GTreeNode));TLNode* trNode = (TLNode*)malloc(sizeof(TLNode));TLNode* cldNode = (TLNode*)malloc(sizeof(TLNode));TLNode* pNode = (TLNode*)LinkList_Get(list,pPos);ret = (cNode != NULL) && (trNode != NULL) && (cldNode != 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(cldNode);}}else{free(cNode);free(trNode);free(cldNode);}}}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;}void GTree_Display(GTree* tree,GTree_Printf* pFunc,char div,int gap){TLNode* trNode = (TLNode*)LinkList_Get(tree,0);if(trNode != NULL){recursive_display(trNode->node,pFunc,0,div,gap);}}GTreeData* GTree_Get(GTree* tree,int pPos){TLNode* trNode = (TLNode*)LinkList_Get(tree,pPos);GTreeData* ret = NULL;if(trNode != NULL){ret = trNode->node->data;}return ret;}int GTree_Count(GTree* tree){return LinkList_Length(tree);}GTreeData* GTree_Root(GTree* tree){return GTree_Get(tree,0);}#include <stdio.h>#include <stdlib.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 Tree Root:\n");printf_data(GTree_Root(tree));printf("\n");printf("After Deleting d:\n");GTree_Display(tree,printf_data,'*',2);printf("After Clearing \n");GTree_Clear(tree);GTree_Display(tree,printf_data,'*',2);GTree_Destroy(tree);return 0;}
相关文章推荐
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- C#实现获取系统目录并以Tree树叉显示的方法
- 数据结构之Treap详解
- C语言实现输入一颗二元查找树并将该树转换为它的镜像
- 用C语言举例讲解数据结构中的算法复杂度结与顺序表
- C#数据结构之堆栈(Stack)实例详解
- C#数据结构之双向链表(DbLinkList)实例详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- 纯jsp打造无限层次的树代码
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort