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