二叉树(c语言)

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;
}

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值