tree.h
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef struct treenode
{
int value;
struct treenode* left;
struct treenode* right;
}node,*pnode;
typedef struct queuenode
{
int val;
struct queuenode* next;
node* left;
node* right;
}queuenode;
typedef struct queue
{
queuenode* first;
queuenode* last;
}queue;
void pretraversal(node& nd);//前序遍历
void midtraversal(node& nd);//中序遍历
void postraversal(node& nd);//后序遍历
int treesize(pnode nd);//节点个数
int leaftsize(pnode nd);//叶子节点个数
int klevelsize(pnode nd,int k);//第k层节点个数
int treedepth(pnode nd);//二叉树的深度
pnode findx(pnode nd, int x);//找到值为x的节点
void leveltraversal(node* nd);//二叉树的层序遍历
void initqueue(queue que);//初始化队列
void pushqueue(queue* que,node* nd);//进入队列
tree.cpp
#define _CRT_SECURE_NO_WARNINGS
#include"tree.h"
void pretraversal(node& nd)
{
assert(&nd);
printf("%d ", nd.value);
if(nd.left!=nullptr)
pretraversal(*nd.left);
if(nd.right!=nullptr)
pretraversal(*nd.right);
}
void midtraversal(node& nd)
{
assert(&nd);
if (nd.left != nullptr)
midtraversal(*nd.left);
printf("%d ", nd.value);
if (nd.right != nullptr)
midtraversal(*nd.right);
}
void postraversal(node& nd)
{
assert(&nd);
if (nd.left != nullptr)
postraversal(*nd.left);
if (nd.right != nullptr)
postraversal(*nd.right);
printf("%d ", nd.value);
}
int treesize(pnode nd)
{
if (nd == nullptr)
return 0;
else
return 1 + treesize(nd->right) + treesize(nd->left);
}
int leaftsize(pnode nd)
{
if (nd == nullptr)
return 0;
if (nd->left == nullptr && nd->right == nullptr)
return 1;
else
return leaftsize(nd->left) + leaftsize(nd->right);
}
int klevelsize(pnode nd,int k)
{
if (nd == nullptr)
return 0;
if (k == 1)
return 1;
else
return klevelsize(nd->left,k-1) + klevelsize(nd->right,k-1);
}
//int treedepth(node* nd)//这是第一种写法
//{
// int k = 1;
// while (klevelsize(nd, k) != 0)
// k++;
// return k - 1;
//}
int treedepth(pnode nd)//这是第二种写法
{
if (nd == nullptr)
return 0;
int leftdepth = treedepth(nd->left);
int rightdepth = treedepth(nd->right);
return leftdepth > rightdepth ? leftdepth + 1 : rightdepth + 1;
}
//这里将递归解释一下,因为的确递归对于初学者来说是肥肠头疼。因为正常来说使用工具的前提是这个工具存在。
//但是递归给人的感觉是这个工具还没有完全的存在就直接使用,电脑会一直递归下去直到边界条件
//就好像是这个工具就实现了。这一点特别的别扭。总的来说就是先想象你已经实现好了这个功能,
//然后用这个功能去实现这个功能更大的一个问题。然后程序会一直递归将一个大问题,递归成一个边界条件时的小问题。、
//所以边界条件是必须且重要的。
//这里那上面treedepth函数举个例子。我们想象我们已经直到了这个节点的左节点的深度和右节点的深度
//那么我们只需要比较左右节点的深度,取大的在加1即可。边界就是这个节点为空。
//其实边界可以很多,这里也可以是这个节点没有孩子节点,那么返回的就是1。
//然后就很容易的写出来了,可能你写出来之后都有点懵,那么你可以具体想一下这个函数的递归调用,
//然后你会发现我们确实是算出了左右两个孩子树的深度,递归会帮我们做到这一点,不妨找一个简单书树试一下。
pnode findx(pnode nd, int x)
{
if (nd == nullptr)
return nullptr;
if (nd->value == x)
return nd;
node* leftfind=findx(nd->left,x);
node* rightfind=findx(nd->right,x);
if (leftfind)
return leftfind;
if (rightfind)
return rightfind;
return nullptr;
}
void initqueue(queue* que)
{
que->first = nullptr;
que->last = nullptr;
}
void pushqueue(queue* que,node* nd)
{
queuenode* newnode=(queuenode*)malloc(sizeof(queuenode));
newnode->val = nd->value;
newnode->left = nd->left;
newnode->right = nd->right;
newnode->next = nullptr;
if (que->first == nullptr)
{
que->first = newnode;
que->last = newnode;
}
else
{
que->last->next = newnode;
que->last = newnode;
}
}
void leveltraversal(node* nd)
{
queue* que=(queue*)malloc(sizeof(queue));
initqueue(que);
if (nd == nullptr)
return;
pushqueue(que, nd);
while (que->first != nullptr)
{
printf("%d ", que->first->val);
if(que->first->left!=nullptr)
pushqueue(que, que->first->left);
if (que->first->right != nullptr)
pushqueue(que, que->first->right);
queuenode* tmp = que->first;
que->first = que->first->next;
free(tmp);
tmp = NULL;
}
}
test.cpp
#define _CRT_SECURE_NO_WARNINGS
#include"tree.h"
node& creatnode(int x)
{
pnode newnode = (pnode)malloc(sizeof(node));
if (newnode == NULL)
{
perror("malloc");
exit(1);
}
newnode->value = x;
newnode->left = nullptr;
newnode->right = nullptr;
return *newnode;
}
int main()
{
node node1 = creatnode(1);
node node2 = creatnode(2);
node node3 = creatnode(3);
node node4 = creatnode(4);
node node5 = creatnode(5);
node node6 = creatnode(6);
pnode pnode1 = &node1;
node1.left = &node2;
node1.right = &node3;
node2.right = &node5;
node2.left = &node4;
node4.right = &node6;
pretraversal(node1);
putchar('\n');
midtraversal(node1);
putchar('\n');
postraversal(node1);
putchar('\n');
int size = treesize(&node1);
printf("%d\n", size);
int leafsize = leaftsize(&node1);
printf("%d\n", leafsize);
int levelsize = klevelsize(&node1, 3);
printf("%d\n", levelsize);
int treedeep = treedepth(&node1);
printf("%d\n", treedeep);
printf("%d\n", (*findx(&node1,3)).value);
leveltraversal(&node1);
return 0;
}