树存储结构(代码、分析、汇编)

目录:

    • 代码:
    • 分析:
    • 汇编:

代码:

LinkList.h
LinkList.c
线性表

GTree.h

#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 pos);//声明删除节点函数GTreeData* GTree_Get(GTree* tree, int pos);//声明获取节点函数GTreeData* GTree_Root(GTree* tree);//声明获取根节点函数int GTree_Height(GTree* tree);//声明获取高度函数int GTree_Count(GTree* tree);//声明获取节点数量函数int GTree_Degree(GTree* tree);//声明获取度数函数void GTree_Display(GTree* tree, GTree_Printf* pFunc, int gap, char div);//声明给每个节点数据进行操作函数#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++)//format 大于0时将输出格式符 div{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);//在每层子节点以2个格式占位符递增}}
}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);//将该节点的空间释放(就是Insert函数中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);//该空间释放(就是Insert函数中cldNode申请的)break;}}               }while( LinkList_Length(node->child) > 0 )//如果删除节点还有子节点{TLNode* trNode = (TLNode*)LinkList_Get(node->child, 0);//取出删除节点中的子节点recursive_delete(list, trNode->node);//将要每个子节点执行同样操作}LinkList_Destroy(node->child);//这必须放在while后面,free(node);//释放树节点空间(就是Insert函数中cNode申请的)这必须放在while后面}}
}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+1。然后返回到上一个节点就相当再加上自己本身的这层}}ret = ret + 1;//加一 表示有一层子节点,只要node(传来的子节点)不为空必须加一}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));//判断表不为空插入的数据不为空与pPos正常if( ret )//条件成功{TLNode* trNode = (TLNode*)malloc(sizeof(TLNode));//新建树节点与链表关联类型// 注意:如果是下面pNode==NULL 。比如插入第一个节点时,后面这个cldNode申请的空间释放不了TLNode* cldNode = (TLNode*)malloc(sizeof(TLNode));//新建树节点与链表关联类型TLNode* pNode = (TLNode*)LinkList_Get(list, pPos);//获取出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"
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);getchar();return 0;
}

分析:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

汇编:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/379185.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python-《twinkle twinkle little star》统计单词出现次数

统计英文儿歌《twinkle twinkle little star》中&#xff0c;使用到的单词及其出现次数。要求去除单词大小写的影响&#xff0c;不统计标点符号的个数&#xff0c;并按降序输出。 Twinkle, twinkle, little star, How I wonder what you are! Up above the world so high, Like…

二元矩阵峰值搜索_好斗的牛(二元搜索)

二元矩阵峰值搜索A farmer has built a long barn with N stalls. The stalls are placed in a straight manner at positions from x1, x2, ...xN. But his cows (C) are aggressive and don’t want to be near other cows. To prevent cows from hurting each other, he wan…

WinForm Paenl里面添加Form

Form7 f7 new Form7();f7.TopLevel false;f7.Parent this.panel1;this.panel1.Controls.Add(f7);f7.Show();转载于:https://www.cnblogs.com/Haibocai/archive/2012/10/30/2746003.html

跳跃表SkipList

跳跃表(Skip List)是一种随机化数据结构&#xff0c;基于并联的链表&#xff0c;其效率可比拟于二叉查找树(对于大多数操作需要O(log n)平均时间)。 基本上&#xff0c;跳跃列表是对有序的链表增加上附加的前进链接&#xff0c;增加是以随机化的方式进行的&#xff0c;所以在列…

Python---冒泡排序、选择排序

冒泡排序 依次输入n个数&#xff0c;进行冒泡排序 冒泡排序法&#xff0c;即两个相邻的进行比较&#xff0c;比较之后换位置 def bubbleSort(arr):n len(arr)for i in range(n):for j in range(0, n-i-1):if arr[j] > arr[j1] :arr[j], arr[j1] arr[j1], arr[j]arr[] n…

react js 添加样式_如何在React JS Application中添加图像?

react js 添加样式Hello! In this article, we will learn how to add images in React JS? I remember when I just started coding in React JS, I thought adding images would be done exactly as it is in HTML. I later realized that it was different. 你好&#xff0…

二叉树(多路平衡搜索树)-(代码、分析、汇编)

目录&#xff1a;代码&#xff1a;分析&#xff1a;汇编&#xff1a;代码&#xff1a; BTree.h #ifndef _BTREE_H_ #define _BTREE_H_#define BT_LEFT 0 //定义左子节点标识 #define BT_RIGHT 1 //定义右子节点标识typedef void BTree;//定义树类型 typedef unsigned long lo…

window service服务安装错误

今天按照园子里面的文章&#xff0c;弄了一个系统服务&#xff0c;可是一直装不上去&#xff0c; 正在运行事务处理安装。 正在开始安装的“安装”阶段。查看日志文件的内容以获得 D:\TecCreateSvc\TecJsCreateService.exe 程序集的进度。该文件位于 D:\TecCreateSvc\TecJsCre…

DM9000调试记录

最近在调试DM9000&#xff0c;遇到了很多问题&#xff0c;在网上几乎也能找到同样的问题&#xff0c;但是答案千变万化&#xff0c;弄的我这样不行&#xff0c;那样也不行。 1、遇到的第一个问题&#xff0c;网卡不识别&#xff0c;出现的调试信息就是&#xff1a; dm9000 dm90…

Python---二分法查找

输入n个数&#xff0c;通过二分法查找该数的下标 def binarySearch(arr,value):m 0#开始n len(arr#最后)while m<n:mid(mn)//2#计算中间位置if valuearr[mid]:#查找成功&#xff0c;返回元素对应的位置return midelif value>arr[mid]:#在后面一半元素中继续查找mmid1e…

Python datetime isocalendar()方法与示例

Python datetime.isocalendar()方法 (Python datetime.isocalendar() Method) datetime.isocalendar() method is used to manipulate objects of datetime class of module datetime. datetime.isocalendar()方法用于操作模块datetime的datetime类的对象。 It uses a dateti…

ASP.NET 技术(附翻译)

1.构建 ASP.NET 页面ASP.NET 和ASP.NET结构ASP.NET 是微软.NET framework整体的一部分, 它包含一组大量的编程用的类&#xff0c;满足各种编程需要。 在下列的二个部分中, 你如何学会 ASP.NET 很适合的放在.NET framework, 和学会能在你的 ASP.NET 页面中使用语言。.NET类库假想…

SQL捕获异常

原文地址 http://technet.microsoft.com/zh-cn/office/ms179296%28vsql.100%29在 Transact-SQL 中使用 TRY...CATCHTransact-SQL 代码中的错误可使用 TRY…CATCH 构造处理&#xff0c;此功能类似于 Microsoft Visual C 和 Microsoft Visual C# 语言的异常处理功能。TRY…CATCH …

二叉树遍历(代码,分析,汇编)

目录&#xff1a;代码&#xff1a;分析&#xff1a;汇编&#xff1a;代码&#xff1a; BTree.h BTree.c 二叉树&#xff08;多路平衡搜索树&#xff09; LinkQueue.h #ifndef _LINKQUEUE_H_ #define _LINKQUEUE_H_typedef void LinkQueue;//定义队列类型LinkQueue* LinkQueu…

Java Vector insertElementAt()方法与示例

矢量类insertElementAt()方法 (Vector Class insertElementAt() method) insertElementAt() method is available in java.util package. insertElementAt()方法在java.util包中可用。 insertElementAt() method is used to set the given element (ele) at the given (indices…

Python---查找序列的最长递增子序列

查找序列的最长递增子序列 什么是序列的最长递增子序列&#xff1f; 答&#xff1a;在一个数值序列中&#xff0c;找到一个子序列&#xff0c;使得这个子序列元素的数值依次递增&#xff0c;并且这个子序列的长度尽可能地大。这就是所谓的最长递增子序列 from itertools impo…

SendMessage和PostMessage

SendMessage 和 PostMessage 的区别 &#xff11;、首先是返回值意义的区别&#xff0c;我们先看一下 MSDN 里的声明&#xff1a; LRESULT SendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);BOOL PostMessage( HWND hWnd…

ffmpeg-从mp4、flv、ts文件中提取264视频流数据

ffmpeg-从mp4、flv、ts文件中提取264视频流数据 main.c #include <stdio.h> #include <libavutil/log.h> #include <libavformat/avio.h> #include <libavformat/avformat.h>void proc(int need_to_annexb, char* in_file, char* out_file) {AVForma…

java timezone_Java TimeZone getDSTSavings()方法与示例

java timezoneTimeZone类的getDSTSavings()方法 (TimeZone Class getDSTSavings() method) getDSTSavings() method is available in java.util package. getDSTSavings()方法在java.util包中可用。 getDSTSavings() method is used to get the number of time differences in …

Photoshop 保存PNG格式交错和不交错有差别

1.PNG格式是由Netscape公司开发出来的格式&#xff0c;可以用于网络图像&#xff0c;但它不同于GIF格式图像只能保存256色&#xff0c;PNG格式可以保存24位的真彩色图像&#xff0c;并且支持透明背景和消除锯齿边缘的功能&#xff0c;可以在不失真的情况下压缩保存图像。但由于…