二叉树的实现

二叉树的实现(包括层序遍历)

queue.h文件

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdbool.h>

typedef struct BinaryTreeNode* QDataType;

typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType x;
}QNode;

typedef struct Queue
{
	QNode* head;//头指针
	QNode* tail;//尾指针
	int size;//队列长度
}Queue;

// 初始化队列 
void QueueInit(Queue* q);
// 队尾入队列 
void QueuePush(Queue* q, QDataType data);
// 队头出队列 
void QueuePop(Queue* q);
// 获取队列头部元素 
QDataType QueueFront(Queue* q);
// 获取队列队尾元素 
QDataType QueueBack(Queue* q);
// 获取队列中有效元素个数 
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q);
// 销毁队列 
void QueueDestroy(Queue* q);

queue.c文件

#include"queue.h" // 引入头文件"queue.h"

// 队列初始化
void QueueInit(Queue* q) // 参数为队列指针
{
    assert(q); // 断言队列指针不为空
    q->head = q->tail = NULL; // 首尾全部指向NULL,即队列为空
    q->size = 0; // 元素个数为0
}

QNode* Buy_Node(QDataType x) // 定义一个函数,用来创建一个新节点
{
    QNode* newnode = (QNode*)malloc(sizeof(QNode)); // 申请一个新节点
    if (newnode == NULL) // 如果申请失败
    {
        perror("malloc fail:"); // 输出错误信息
        return 0; // 返回0
    }
    newnode->x = x; // 新节点的数据为x
    newnode->next = NULL; // 新节点的next指针指向NULL,即没有下一个节点
    return newnode; // 返回新节点
}

// 队头入队列 
void QueuePush(Queue* q, QDataType data) // 参数为队列指针和要插入的数据
{
    assert(q); // 断言队列指针不为空
    QNode* newnode = Buy_Node(data); // 创建一个新节点
    if (q->head == NULL) // 如果队列为空
    {
        assert(q->tail == NULL); // 断言队列尾指针也为空
        q->head = q->tail = newnode; // 头指针和尾指针都指向新节点
    }
    else // 如果队列不为空
    {
        q->tail->next = newnode; // 队列尾部的next指针指向新节点
        q->tail = newnode; // 队列尾指针指向新节点
    }
    q->size++; // 元素个数加1
}

// 队头出队列 
void QueuePop(Queue* q) // 参数为队列指针
{
    assert(q); // 断言队列指针不为空
    assert(q->head != NULL); // 断言队列头指针不为空
    if (q->head->next == NULL) // 如果队列只有一个元素
    {
        free(q->head); // 释放头节点的内存
        q->head = q->tail = NULL; // 头指针和尾指针都指向NULL,即队列为空
    }
    else // 如果队列不止一个元素
    {
        QNode* second = q->head->next; // 保存第二个节点的指针
        free(q->head); // 释放头节点的内存
        q->head = second; // 将原来的第二个节点设置为头节点
    }
    q->size--; // 元素个数减1
}

// 获取队列头部元素 
QDataType QueueFront(Queue* q) // 参数为队列指针
{
    return q->head->x; // 返回头节点的数据
}

// 获取队列队尾元素 
QDataType QueueBack(Queue* q) // 参数为队列指针
{
    return q->tail->x; // 返回尾节点的数据
}

// 获取队列中有效元素个数 
int QueueSize(Queue* q) // 参数为队列指针
{
    return q->size; // 返回元素个数
}

// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q) // 参数为队列指针
{
    return q->size == 0; // 如果元素个数为0,返回1,否则返回0
}

// 销毁队列 
void QueueDestroy(Queue* q) // 参数为队列指针
{
    assert(q); // 断言队列指针不为空
    QNode* cur = q->head; // 定义一个指针cur指向队列头节点
    while (cur) // 循环直到cur为NULL
    {
        QNode* second = cur->next; // 保存下一个节点的指针
        free(cur); // 释放当前节点的内存
        cur = second; // 将cur指向下一个节点
    }
    q->head = q->tail = NULL; // 头指针和尾指针都指向NULL,即队列为空
    q->size = 0; // 元素个数为0
}

test.c文件

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include"queue.h"

typedef int BTDataType;

typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;

BTNode* BuyNode(BTDataType x)
{
	BTNode* node = (BTNode*)malloc(sizeof(BTNode));
	if (node == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	node->data = x;
	node->left = NULL;
	node->right = NULL;
	return node;
}

BTNode* CreatTree()
{
	//创建节点
	BTNode* node1 = BuyNode(1);
	BTNode* node2 = BuyNode(2);
	BTNode* node3 = BuyNode(3);
	BTNode* node4 = BuyNode(4);
	BTNode* node5 = BuyNode(5);
	BTNode* node6 = BuyNode(6);
	BTNode* node7 = BuyNode(7);
	BTNode* node8 = BuyNode(8);
	BTNode* node9 = BuyNode(9);
	BTNode* node10 = BuyNode(10);
	
	//建树
	node1->left = node2;
	node1->right = node4;

	node2->left = node3;
	node4->left = node5;
	node4->right = node6;
	node3->right = node7;
	node7->left = node8;
	node5->right = node9;
	node9->left = node10;
	return node1;
}

// 二叉树前序遍历 
//前序遍历为 中->左->右
void PreOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL->");
		return;
	}
	printf("%d->", root->data);
	PreOrder(root->left);
	PreOrder(root->right);
}

// 二叉树中序遍历
//中序遍历为 左->中->右
void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL->");
		return;
	}
	InOrder(root->left);
	printf("%d->", root->data);
	InOrder(root->right);
}

// 二叉树后序遍历
//后序遍历为 左->右->中
void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL->");
		return;
	}
	PostOrder(root->left);
	PostOrder(root->right);
	printf("%d->", root->data);
}

//求节点的个数
int TreeSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	return TreeSize(root->left)+ TreeSize(root->right) + 1;//递归了左子树,然后递归右子树,再加上自身的节点数(1)
}

//求高度
int TreeHeight(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	int LeftHight = TreeHeight(root->left);
	int RightHight = TreeHeight(root->right);
	return LeftHight > RightHight ? LeftHight + 1 : RightHight + 1;
}

//得到第k层有多少个节点
int TreeKLevel(BTNode* root, int k)
{
	assert(k > 0);

	if (root == NULL)
	{
		return 0;
	}

	if (k == 1)
	{
		return 1;
	}
	int left = TreeKLevel(root->left, k - 1);
	int right = TreeKLevel(root->right, k - 1);
	return left + right;
	//return TreeKLevel(root->left, k - 1) + TreeKLevel(root->right, k - 1);
}

BTNode* TreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
	{
		return NULL;
	}

	if (root->data == x)
	{
		return root;
	}

	BTNode* left = TreeFind(root->left,x);
	if (left != NULL)
	{
		return left;
	}
	BTNode* right = TreeFind(root->right,x);
	if (right != NULL)
	{
		return right;
	}
	return NULL;
}

//层序遍历->宽度优先搜索
void BFS(BTNode* root)
{
	Queue q;//建立队列
	QueueInit(&q);//初始化队列
	if (root)
	{
		QueuePush(&q, root);//先将第一个节点入队列
	}
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);//出队
		printf("%d->", front->data);
		if (front->left)
		{
			QueuePush(&q, front->left);
		}

		if (front->right)
		{
			QueuePush(&q, front->right);
		}
	}
	//销毁队列
	QueueDestroy(&q);
}

int main(void)
{
	BTNode* root=CreatTree();
	printf("前序遍历: ");
	PreOrder(root);
	puts("");
	printf("中序遍历: ");
	InOrder(root);
	puts("");
	printf("后序遍历: ");
	PostOrder(root);
	puts("");
	printf("节点个数为:%d", TreeSize(root));
	puts("");
	printf("树的高度为: %d", TreeHeight(root));
	puts("");
	printf("第3层有%d个节点", TreeKLevel(root, 3));
	puts("");
	BTNode* find = TreeFind(root, 5);
	PreOrder(find);
	puts("");
	BFS(root);
	return 0;
}

posted @ 2023-08-24 22:28  Hayaizo  阅读(4)  评论(0编辑  收藏  举报