定义
- 树是节点的优先集合
- 度:孩子的数量,度为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 int
typedef 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 3
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 int
typedef 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;
}