目录
一 树的链式存储结构
二 树的链式结构简单实现
1.基本结构
2.结点创建
3.前中后序遍历为深度优先遍历,层序遍历为广度优先遍历
4.求结点个数
5.求叶子结点个数
6.求第K层结点个数
7.查找树里面值为x的那个结点
8.销毁树
9.判断一棵树是不是完全二叉树
三 完整文件
1.BinaryTree.h
2.BinaryTree.c
3.test.c
四 总结
1.四种遍历顺序:前序遍历(先根)、中序遍历(中根)、后序遍历(后根)、层序遍历。
2.递归:①子问题。②结束条件。
3.排序二叉树:①又称二叉搜索树,它的左孩子都小于父亲,右孩子都大于父亲。②普通二叉树的增删查改没有意义,排序二叉树的增删查改才有意义。③极端情况下(数据为有序数列),搜索二叉树的效率退化为O(N)。④二叉搜索树的中序遍历为升序。
typedef char BTDateType;
typedef struct BinaryTreeNode
{
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
BTDateType date;
}BTNode;
//创建一颗二叉树
BTNode* CreateTreeNode(BTDateType x)
{
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
if (node == NULL)
{
printf("malloc fail\n");
exit(-1);
}
node->date = x;
node->left = NULL;
node->right = NULL;
return node;
}
//前序遍历
void PrevOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
printf("%c ", root->date);
PrevOrder(root->left);
PrevOrder(root->right);
}
//中序遍历
void InOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
InOrder(root->left);
printf("%c ", root->date);
InOrder(root->right);
}
//后续遍历
void PostOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
PostOrder(root->left);
PostOrder(root->right);
printf("%c ", root->date);
}
//层序遍历(广度优先遍历)
void TreeLevelOrder(BTNode* root)
{
Queue q;
QueueInit(&q);
if (root)
{
QueuePush(&q,root);
}
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
printf("%c ", front->date);
if (front->left)
{
QueuePush(&q, front->left);
}
if (front->right)
{
QueuePush(&q, front->right);
}
}
QueueDestroy(&q);
}
求树的结点个数,思路一:遍历。
//void TreeSize(BTNode* root, int* size)
//{
// if (root == NULL)
// {
// return;
// }
// ++(*size);
// TreeSize(root->left, size);
// TreeSize(root->right,size);
//}
//思路二:分治算法(把大问题拆解成子问题)
int TreeSize(BTNode* root)
{
return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}
//求叶子结点个数
int TreeLeafSize(BTNode* root)
{
if (root == NULL)
{
return 0;
}
if (root->left == NULL && root->right == NULL)
{
return 1;
}
return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}
//求第K层结点个数:k>0(转化为求左孩子的K-1层+右孩子的K-1层)
int TreeKlevelSize(BTNode* root, int k)
{
if (root == NULL)
{
return 0;
}
if (k == 1)
{
return 1;
}
return TreeKlevelSize(root->left, k - 1) + TreeKlevelSize(root->right, k - 1);
}
//查找树里面值为x的那个结点
BTNode* TreeFind(BTNode* root, BTDateType x)
{
if (root == NULL)
{
return NULL;
}
if (root->date == x)
{
return root;
}
BTNode* ltemp = TreeFind(root->left, x);
if (ltemp)
return ltemp;
BTNode* rtemp = TreeFind(root->right, x);
if(rtemp)
return rtemp;
return NULL;
}
//销毁树(传一级指针,调用此函数的人自己将指针置空,保持接口的一致性)
void BinaryTreeDestory(BTNode* root)
{
if (root == NULL)
{
return;
}
BinaryTreeDestory(root->left);
BinaryTreeDestory(root->right);
free(root);
}
9.1完全二叉树按层序走,结点是连续的,当出到空了以后,后面全是空就是完全二叉树,如果后面有非空,那么就不是。(因为说明层序走,非空结点不连续。)
9.2判断是不是完全二叉树代码实现
//判断是不是完全二叉树
bool BinaryTreeComplete(BTNode* root)
{
Queue q;
QueueInit(&q);
if (root!=NULL)
{
QueuePush(&q, root);
}
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
if (front==NULL)
{
break;
}
QueuePush(&q, front->left);
QueuePush(&q, front->right);
}
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
if (front!=NULL)
{
return false;
}
}
QueueDestroy(&q);
return true;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#include
#include
typedef char BTDateType;
typedef struct BinaryTreeNode
{
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
BTDateType date;
}BTNode;
BTNode* CreateTreeNode(BTDateType x);
void PrevOrder(BTNode* root);
void InOrder(BTNode* root);
void PostOrder(BTNode* root);
//void TreeSize(BTNode* root, int* size);
int TreeSize(BTNode* root);
int TreeLeafSize(BTNode* root);
int TreeKlevelSize(BTNode* root, int k);
BTNode* TreeFind(BTNode* root, BTDateType x);
//求第K层结点个数:(转化为求左孩子的K-1层+右孩子的K-1层)
int TreeKlevelSize(BTNode* root, int k);
//查找树里面值为x的那个结点
BTNode* TreeFind(BTNode* root, BTDateType x);
//销毁树(传一级指针,调用此函数的人自己将指针置空,保持接口的一致性)
void BinaryTreeDestory(BTNode* root);
//层序遍历(广度优先遍历)
void TreeLevelOrder(BTNode* root);
//判断是否为完全二叉树
bool BinaryTreeComplete(BTNode* root);
#define _CRT_SECURE_NO_WARNINGS 1
#include"BinaryTree.h"
#include"queue.h"
//创建一颗二叉树
BTNode* CreateTreeNode(BTDateType x)
{
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
if (node == NULL)
{
printf("malloc fail\n");
exit(-1);
}
node->date = x;
node->left = NULL;
node->right = NULL;
return node;
}
//前序遍历
void PrevOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
printf("%c ", root->date);
PrevOrder(root->left);
PrevOrder(root->right);
}
//中序遍历
void InOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
InOrder(root->left);
printf("%c ", root->date);
InOrder(root->right);
}
//后续遍历
void PostOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
PostOrder(root->left);
PostOrder(root->right);
printf("%c ", root->date);
}
求树的结点个数,思路一:遍历。
//void TreeSize(BTNode* root, int* size)
//{
// if (root == NULL)
// {
// return;
// }
// ++(*size);
// TreeSize(root->left, size);
// TreeSize(root->right,size);
//}
//思路二:分治算法(把大问题拆解成子问题)
int TreeSize(BTNode* root)
{
return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}
//求叶子结点个数
int TreeLeafSize(BTNode* root)
{
if (root == NULL)
{
return 0;
}
if (root->left == NULL && root->right == NULL)
{
return 1;
}
return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}
//求第K层结点个数:k>0(转化为求左孩子的K-1层+右孩子的K-1层)
int TreeKlevelSize(BTNode* root, int k)
{
if (root == NULL)
{
return 0;
}
if (k == 1)
{
return 1;
}
return TreeKlevelSize(root->left, k - 1) + TreeKlevelSize(root->right, k - 1);
}
//查找树里面值为x的那个结点
BTNode* TreeFind(BTNode* root, BTDateType x)
{
if (root == NULL)
{
return NULL;
}
if (root->date == x)
{
return root;
}
BTNode* ltemp = TreeFind(root->left, x);
if (ltemp)
return ltemp;
BTNode* rtemp = TreeFind(root->right, x);
if(rtemp)
return rtemp;
return NULL;
}
//销毁树(传一级指针,调用此函数的人自己将指针置空,保持接口的一致性)
void BinaryTreeDestory(BTNode* root)
{
if (root == NULL)
{
return;
}
BinaryTreeDestory(root->left);
BinaryTreeDestory(root->right);
free(root);
}
//层序遍历(广度优先遍历)
void TreeLevelOrder(BTNode* root)
{
Queue q;
QueueInit(&q);
if (root)
{
QueuePush(&q,root);
}
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
printf("%c ", front->date);
if (front->left)
{
QueuePush(&q, front->left);
}
if (front->right)
{
QueuePush(&q, front->right);
}
}
QueueDestroy(&q);
}
//判断是不是完全二叉树
bool BinaryTreeComplete(BTNode* root)
{
Queue q;
QueueInit(&q);
if (root!=NULL)
{
QueuePush(&q, root);
}
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
if (front==NULL)
{
break;
}
QueuePush(&q, front->left);
QueuePush(&q, front->right);
}
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
if (front!=NULL)
{
return false;
}
}
QueueDestroy(&q);
return true;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include"BinaryTree.h"
#include"queue.h"
int main()
{
BTNode* A = CreateTreeNode('A');
BTNode* B = CreateTreeNode('B');
BTNode* C = CreateTreeNode('C');
BTNode* D = CreateTreeNode('D');
BTNode* E = CreateTreeNode('E');
//BTNode* F = CreateTreeNode('F');
BTNode* G = CreateTreeNode('G');
A->left = B;
A->right = C;
B->left = D;
B->right = E;
//C->left = F;
C->right = G;
//PrevOrder(A);
//printf("\n\n");
//InOrder(A);
//printf("\n\n");
//PostOrder(A);
//int size = 0;
//TreeSize(A, &size);
//printf("%d\n",size);
// size = 0;
//TreeSize(A, &size);
//printf("%d\n", size);
printf("%d\n", TreeLeafSize(A));
printf("%d\n", TreeLeafSize(A));
printf("%d\n", TreeKlevelSize(A,3));
//printf("%p\n", F);
//printf("%p\n",TreeFind(A,'F'));
TreeLevelOrder(A);
printf("%d\n", BinaryTreeComplete(A));
BinaryTreeDestory(A);
A = NULL;
return 0;
}
1.深度优先遍历:前中后序遍历,一般用递归。
2.广度优先遍历:层序遍历,一般借助队列。
3.求结点的个数(前序),左子树结点个数+右子树结点个数+1。
4.求树的高度(后序),fmax(左树高度,右树高度)+1。