数据结构 树

定义

  • 树是节点的优先集合

  • 度:孩子的数量,度为0 就是终端节点,不为零就是根节点
  • 有序树:有顺序,不可以替换
  • 无序树:无顺序,可以替换

  • 深度 和 树的深度相反,第一层深度为1 
  • 树的深度为 3

二叉树

 

  • 满二叉树每一层的节点达到最大
  • 完全二叉树  从头部开始,从左往右依次读数,存在的数据和满二叉树的位置一一对应就是完全二叉树
  • 满二叉树是完全二叉树
  • 完全二叉树不是满二叉树

二叉树的存储结构

顺序存储

链式存储

代码

数组二叉树


/************************************************************************/
/*  树课程要求:完成树的基本操作1. 树的创建和销毁2. 树中节点的搜索3. 树中节点的添加与删除4. 树中节点的遍历BOOL CreateTree(Tree **pTree, Node *pRoot);                           //创建树void DestroyTree(Tree *pTree);                                        //销毁树Node *SearchNode(Tree *pTree, int nodeIndex);                         //根据索引寻找节点BOOL AddNode(Tree *pTree, int nodeIndex, int direction, Node *pNode); //添加节点BOOL DeleteNode(Tree *pTree, int nodeIndex, Node *pNode);             //删除节点void PreorderTraversal(Tree *pTree);                                  //前(先)序遍历演示void InorderTraversal(Tree *pTree);                                   //中序遍历演示void PostorderTraversal(Tree *pTree);                                 //后序遍历演示void TreeTraverse(Tree *pTree);                                       //遍历七日成蝶-叩开数据结构之门(链表)关于数组与树之间的算法转换int    3 5 8 2 6 9 7        父亲结点下标*2+1  该结点左  父亲结点下标*2+2  该结点右3(0)5(1)            8(2)2(3)      6(4)   9(5)       7(6)
*/
/************************************************************************/#include <stdio.h>
#include <stdlib.h>#define MAX_NODE 20
#define LEFT  1
#define RIGHT 2
#define FALSE 0
#define TRUE  1
#define BOOL inttypedef struct tag_node
{int data;
}Node;typedef struct tag_tree
{Node *root;
}Tree;BOOL CreateTree(Tree **pTree, Node *pRoot)
{*pTree = (Tree *)malloc(sizeof(Tree));if(*pTree == NULL){return FALSE;}(*pTree)->root = (Node *)malloc(sizeof(Node) * MAX_NODE);if((*pTree)->root == NULL){free(*pTree);return FALSE;}for(int i = 0; i < MAX_NODE; i++){(*pTree)->root[i].data = 0;}(*pTree)->root[0] = *pRoot;  //(*pTree)->root[0].data = pRoot->data;return TRUE;
}void DestroyTree(Tree *pTree)
{free(pTree->root);pTree->root = NULL;free(pTree);pTree = NULL;
}Node *SearchNode(Tree *pTree, int nodeIndex)
{if(nodeIndex < 0 || nodeIndex >= MAX_NODE){return NULL;}if(pTree->root[nodeIndex].data == 0){return NULL;}else{return &(pTree->root[nodeIndex]);}
}//BOOL SearchNode(Tree *pTree, int nodeIndex, Node *node)
//{
//	if(nodeIndex < 0 || nodeIndex >= MAX_NODE)
//	{
//		return FALSE;
//	}
//
//	if(pTree->root[nodeIndex].data == 0)
//	{
//		return FALSE;
//	}
//	else
//	{
//		node->data = pTree->root[nodeIndex].data;  //*node = pTree->root[nodeIndex];
//
//		
//		return TRUE;
//	}
//}BOOL AddNode(Tree *pTree, int nodeIndex, int direction, Node *pNode)
{if(nodeIndex < 0 || nodeIndex >= MAX_NODE){return FALSE;}if(pTree->root[nodeIndex].data == 0){return FALSE;}pTree->root[nodeIndex * 2 + direction].data = pNode->data; //pTree->root[nodeIndex * 2 + direction] = *pNode;return TRUE;
}BOOL DeleteNode(Tree *pTree, int nodeIndex, Node *pNode)
{if(nodeIndex < 0 || nodeIndex >= MAX_NODE){return FALSE;}if(pTree->root[nodeIndex].data == 0){return FALSE;}*pNode = pTree->root[nodeIndex];pTree->root[nodeIndex].data = 0;return TRUE;
}void TreeTraverse(Tree *pTree)
{for(int i = 0; i < MAX_NODE; i++){printf("%d ", pTree->root[i].data);}
}int main(void)
{Tree *pTree = NULL;Node node = {3};Node node1 = {5};Node node2 = {8};Node node3 = {2};Node node4 = {6};Node node5 = {9};Node node6 = {7};CreateTree(&pTree, &node);AddNode(pTree, 0, LEFT, &node1);AddNode(pTree, 0, RIGHT, &node2);AddNode(pTree, 1, LEFT, &node3);AddNode(pTree, 1, RIGHT, &node4);AddNode(pTree, 2, LEFT, &node5);AddNode(pTree, 2, RIGHT, &node6);TreeTraverse(pTree);DestroyTree(pTree);system("pause");return 0;
}

链表 二叉树


/************************************************************************/
/*  树课程要求:完成树的基本操作1. 树的创建和销毁2. 树中节点的搜索3. 树中节点的添加与删除4. 树中节点的遍历BOOL CreateTree(Tree **pTree, Node *pRoot);                           //创建树void DestroyTree(Tree *pTree);                                        //销毁树Node *SearchNode(Tree *pTree, int nodeIndex);                         //根据索引寻找节点BOOL AddNode(Tree *pTree, int nodeIndex, int direction, Node *pNode); //添加节点BOOL DeleteNode(Tree *pTree, int nodeIndex, Node *pNode);             //删除节点void PreorderTraversal(Tree *pTree);                                  //前(先)序遍历演示void InorderTraversal(Tree *pTree);                                   //中序遍历演示void PostorderTraversal(Tree *pTree);                                 //后序遍历演示七日成蝶-叩开数据结构之门(链表)七日成蝶-C语言编程基础3 5 8 2 6 9 7        前序遍历:3 5 2 6 8 9 7  中序遍历:2 5 6 3 9 8 7后序遍历:2 6 5 9 7 8 33(0)5(1)            8(2)2(3)      6(4)   9(5)       7(6)
*/
/************************************************************************/#include <stdio.h>
#include <stdlib.h>//#define MAX_NODE 20
#define LEFT  1
#define RIGHT 2
#define FALSE 0
#define TRUE  1
#define BOOL inttypedef struct tag_node
{int index;int data;struct tag_node *pLChild;struct tag_node *pRChild;struct tag_node *pParent;
}Node;typedef struct tag_tree
{Node *root;
}Tree;BOOL CreateTree(Tree **pTree, Node *pRoot);
void DestroyTree(Tree *pTree);
void DeleteNodeEx(Node *pNode, int direction);
Node *SearchNode(Tree *pTree, int nodeIndex);
Node *SearchNodeEx(Node *pNode, int nodeIndex);
BOOL AddNode(Tree *pTree, int nodeIndex, int direction, Node *pNode);
BOOL DeleteNode(Tree *pTree, int nodeIndex, Node *pNode);
void PreorderTraversal(Tree *pTree);
void PreorderTraversalNode(Node *pNode);
void InorderTraversal(Tree *pTree);
void InorderTraversalNode(Node *pNode);
void PostorderTraversal(Tree *pTree);
void PostorderTraversalNode(Node *pNode);BOOL CreateTree(Tree **pTree, Node *pRoot)
{*pTree = (Tree *)malloc(sizeof(Tree));if(*pTree == NULL){return FALSE;}(*pTree)->root = (Node *)malloc(sizeof(Node));if((*pTree)->root == NULL){free(*pTree);return FALSE;}*((*pTree)->root) = *pRoot; /*(*pTree)->root->data = pRoot->data;(*pTree)->root->index = pRoot->index;(*pTree)->root->pLChild = NULL;(*pTree)->root->pRChild = NULL;(*pTree)->root->pParent = NULL;*/return TRUE;
}void DestroyTree(Tree *pTree)
{DeleteNodeEx(pTree->root->pLChild, LEFT);DeleteNodeEx(pTree->root->pRChild, RIGHT);free(pTree->root);pTree->root = NULL;free(pTree);pTree = NULL;
}void DeleteNodeEx(Node *pNode, int direction)
{if(pNode != NULL){DeleteNodeEx(pNode->pLChild, LEFT);DeleteNodeEx(pNode->pRChild, RIGHT);if(direction == LEFT){pNode->pParent->pLChild = NULL;}if(direction == RIGHT){pNode->pParent->pRChild = NULL;}free(pNode);pNode = NULL;}}Node *SearchNode(Tree *pTree, int nodeIndex)
{return SearchNodeEx(pTree->root, nodeIndex);
}Node *SearchNodeEx(Node *pNode, int nodeIndex)
{if(pNode == NULL){return NULL;}if(pNode->index == nodeIndex){return pNode;}else{Node *temp = NULL;temp = SearchNodeEx(pNode->pLChild, nodeIndex);if(temp != NULL){return temp;}temp = SearchNodeEx(pNode->pRChild, nodeIndex);return temp;}
}//BOOL SearchNode(Tree *pTree, int nodeIndex, Node *node)
//{
//	if(nodeIndex < 0 || nodeIndex >= MAX_NODE)
//	{
//		return FALSE;
//	}
//
//	if(pTree->root[nodeIndex].data == 0)
//	{
//		return FALSE;
//	}
//	else
//	{
//		node->data = pTree->root[nodeIndex].data;  //*node = pTree->root[nodeIndex];
//
//		
//		return TRUE;
//	}
//}BOOL AddNode(Tree *pTree, int nodeIndex, int direction, Node *pNode)
{Node *temp = SearchNode(pTree, nodeIndex);Node *newNode = NULL;if(temp == NULL){return FALSE;}if(direction == LEFT){if(temp->pLChild == NULL){newNode = (Node *)malloc(sizeof(Node));if(newNode == NULL){return FALSE;}*newNode = *pNode;temp->pLChild = newNode;newNode->pParent = temp;}else{return FALSE;}}else{if(temp->pRChild == NULL){newNode = (Node *)malloc(sizeof(Node));if(newNode == NULL){return FALSE;}*newNode = *pNode;temp->pRChild = newNode;newNode->pParent = temp;}else{return FALSE;}}return TRUE;
}BOOL DeleteNode(Tree *pTree, int nodeIndex, Node *pNode)
{Node *temp = SearchNode(pTree, nodeIndex);if(temp == NULL){return FALSE;}*pNode = *temp;DeleteNodeEx(temp->pLChild, LEFT);DeleteNodeEx(temp->pRChild, RIGHT);if(temp->pParent->pLChild == temp){temp->pParent->pLChild = NULL;}if(temp->pParent->pRChild == temp){temp->pParent->pRChild = NULL;}free(temp);temp = NULL;return TRUE;
}//void TreeTraverse(Tree *pTree)
//{
//	for(int i = 0; i < MAX_NODE; i++)
//	{
//		printf("%d ", pTree->root[i].data);
//	}
//}void PreorderTraversal(Tree *pTree)
{PreorderTraversalNode(pTree->root);
}void PreorderTraversalNode(Node *pNode)
{if(pNode != NULL){printf("%d ", pNode->data);PreorderTraversalNode(pNode->pLChild);PreorderTraversalNode(pNode->pRChild);}
}void InorderTraversal(Tree *pTree)
{InorderTraversalNode(pTree->root);
}void InorderTraversalNode(Node *pNode)
{if(pNode != NULL){InorderTraversalNode(pNode->pLChild);printf("%d ", pNode->data);InorderTraversalNode(pNode->pRChild);}
}void PostorderTraversal(Tree *pTree)
{PostorderTraversalNode(pTree->root);
}void PostorderTraversalNode(Node *pNode)
{if(pNode != NULL){PostorderTraversalNode(pNode->pLChild);PostorderTraversalNode(pNode->pRChild);printf("%d ", pNode->data);}
}int main(void)
{Tree *pTree = NULL;Node node = {0, 3, NULL, NULL, NULL};Node node1 = {1, 5, NULL, NULL, NULL};Node node2 = {2, 8, NULL, NULL, NULL};Node node3 = {3, 2, NULL, NULL, NULL};Node node4 = {4, 6, NULL, NULL, NULL};Node node5 = {5, 9, NULL, NULL, NULL};Node node6 = {6, 7, NULL, NULL, NULL};CreateTree(&pTree, &node);AddNode(pTree, 0, LEFT, &node1);AddNode(pTree, 0, RIGHT, &node2);AddNode(pTree, 1, LEFT, &node3);AddNode(pTree, 1, RIGHT, &node4);AddNode(pTree, 2, LEFT, &node5);AddNode(pTree, 2, RIGHT, &node6);//PreorderTraversal(pTree);//InorderTraversal(pTree);PostorderTraversal(pTree);DestroyTree(pTree);system("pause");return 0;
}

 

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

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

相关文章

英语口语 Week15 TuesDay

英语文章 One day, when Bella was doing sports in the school yard, the squirrel fled out of her sleeve. Threading its way through a considerable number of people, the squirrel disappeared in the distance After a sequence of movements, it hopped onto the ar…

c++面向对象高级编程 学习十四 引用

文章目录referencereference的常见用途reference 变量有三种形式&#xff1a;值&#xff0c;指针&#xff0c;引用 int x0; //值 int* p&x;//指向整型的指针&#xff0c;地址&#xff0c;指针在之后的程序中可以指向其他变量 int& rx;//引用&#xff0c;此处表示 r代…

google浏览器 隐藏功能开启

网址 chrome://flags/ 1&#xff0c;多线程下载 2&#xff0c;暗黑模式3&#xff0c;标签缩略图4&#xff0c;PWA 渐进式web应用 网页即应用5&#xff0c;阅读模式&#xff0c;排除广告&#xff0c;点击阅读模式去除干扰chrome://net-internals6&#xff0c;解决有问题的代理IP…

英语口语Week 15 Wednesday

英语文章 Accomplishing the task assigned by the teacher; Julia rushed out. Squatting at the gate and playing with the squirrel, Bella waved at the sight of Julia and yelled out here" . Julia ran quickly towards them, pointed at the squirrel and asked…

c++面向对象高级编程 学习十五 组合继承关系下的构造和析构

文章目录继承关系组合关系继承和组合继承关系 构造由内而外&#xff0c;析构由外而内&#xff0c;内即是父类 组合关系 A拥有B&#xff0c; 构造由内而外&#xff0c;析构由外而内&#xff0c;内即是B 继承和组合 构造和析构顺序如图&#xff1a;

英语口语Week16 Wednesday

英语文章 Recently my friend received a gift from her boyfriend - a very expensive bracelet. But the substance of her response left us in astonishment - she didn’t attend to the exquisiteness(of the gift and wanted to return it to him In terms of salary, …

C++ 查漏补缺

特性关系 C语言面向过程C面向过程 面向对象(封装 继承 多态)C具备C语言的全部特性的基础上&#xff0c;并且支持更多新的特性 内存泄露 申请内存&#xff0c;没有释放申请 malloc new释放 free deleteProcessExplorer查看内存是否释放 代码移植 将生成的exe运行在别的平台&…

c++面向对象高级编程 学习十六 vptr和vtbl

当一个类中有一个或多个虚函数时&#xff0c;内存中会多一个虚指针&#xff08;vptr&#xff0c;virtual pointer&#xff09;&#xff0c;指向一个虚表&#xff08;vtbl&#xff0c;virtual table&#xff09; 父类有虚函数&#xff0c;则子类一定有虚函数 在下图示意图中&a…

英语口语Week16 Thursday

英语文章 It is an impossibility that everything runs smoothly in everyday life. Where there is trouble, there could be anxiety.Anxiety is a common phenomenon; you are not the only one carrying it. But, it could be somewhat poisonous if you don’t let it o…

static内容相关介绍学习

说一下static关键字的作用 当程序执行到函数内部定义的变量时&#xff0c;编译器为它在栈上分配空间&#xff0c;函数在栈上分配的空间在此函数执行结束时会释放掉&#xff0c;这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时&#xff0c;如何实现&#xf…

C++STL与泛型编程(2) 第一个C++ STL Application

文章目录STL六大部件STL六大部件代码示例时间复杂度前闭后开区间auto关键字的用法STL六大部件 容器 分配器 算法 迭代器 适配器 仿函数 容器要放东西&#xff0c;东西要占用内存&#xff0c;分配器可支持容器解决内存问题。算法处理容器中的数据。迭代器是容器和算法之间的桥…

C++STL与泛型编程(3)容器之分类与测试

文章目录容器的分类序列式容器&#xff08;sequence containers&#xff09;代码示例辅助函数array 容器array容器的测试代码测试代码中部分函数解析vector 容器vector 容器的测试代码测试代码中部分函数解析list 容器list 容器的测试代码测试代码中部分函数解析forward_list 容…

C++面试题目

C和C的区别 总览 C是一个结构化语言&#xff0c;它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程&#xff0c;对输入&#xff08;或环境条件&#xff09;进行运算处理得到输出&#xff08;或实现过程&#xff08;事务&#xff09;控制&#xff09;。C&…

C++STL与泛型编程(4)OOP(面向对象编程) Vs. GP(泛型编程)

文章目录OOP和GP为什么list不能使用标准库中的::sort算法&#xff1f;采用GP的好处OOP和GP OOP将datas和methods关联在一起 GP将datas和methods分开 为什么list不能使用标准库中的::sort算法&#xff1f; 因为标准库的sort的算法用到了随机访问迭代器&#xff08;RandomAcce…

牛客网 链表结构 算法相关内容

链表结构 单链表的节点结构 由以下结构的节点依次连接起来所形成的链叫单链表结构 Clas Node<V>{ V value; Node next; } 双链表的节点结构 由以下结构的节点依次连接起来所形成的链叫双链表结构 Clas Node<V>{ V value; Node next; Node last; } 单链表和双…

C++ primer 第8章 IO库

文章目录IO库类型和头文件IO对象无拷贝或赋值IO流的条件状态文件输入输出ifstream 示例ofstream 示例文件模式以out模式打开文件会丢弃已有数据每次调用open时都会确定文件模式ofstream 保留源文件 追加数据 示例string流istringstream示例ostringstream示例IO库类型和头文件 …

C++面试宝典 基本语言(三)

如果同时定义了两个函数&#xff0c;一个带const&#xff0c;一个不带&#xff0c;会有问题吗&#xff1f; 不会&#xff0c;这相当于函数的重载 #include<iostream> class A{ public:void print()const{std::cout << "Hello" << std::endl;}void…

C++ primer 第9章 顺序容器

文章目录顺序容器类型确定使用哪种顺序容器容器库概览容器操作迭代器迭代器支持的所有操作迭代器支持的所有运算迭代器范围对构成范围的迭代器的要求标准库迭代器范围左闭右开的三种性质容器定义和初始化将一个新容器创建为另一个容器的拷贝将array拷贝到vector中的代码与顺序容…

牛客网C++面经 容器和算法

原文网址 参考网址 C语言中文网 请你来说一下map和set有什么区别&#xff0c;分别又是怎么实现的&#xff1f; map和set都是C的关联容器&#xff0c;其底层实现都是红黑树&#xff08;RB-Tree&#xff09;。由于 map 和set所开放的各种操作接口&#xff0c;RB-tree 也都提供…

C++ primer 第10章 泛型算法

文章目录概述findcount初识泛型算法只读算法只读算法accumulate只读算法equal写容器元素的算法算法fill算法fill_nback_inserter算法copy算法replace replace_copy重排容器元素的算法sortuniqueunique_copy定制操作向算法传递函数谓词算法stable_sort算法partitionlambda表达式…