C语言二叉树的实现

二叉树前序遍历

  • 打印当前节点,将该节点入栈。如果该节点有左子树,访问左子树,重复此步骤,直到没有左子树。
  • 访问栈顶元素的右孩子,并出栈。重复1的操作。
  • 当栈为空且指针为空时,遍历结束。

二叉树中序遍历

  • 将当前节点入栈。如果有左孩子,访问左孩子,重复此步骤,直至没有左孩子。
  • 打印栈顶元素,出栈,访问栈顶右孩子,重复步骤1。
  • 当栈为空且指针为空时遍历结束。

二叉树后序遍历

  • 将当前节点入栈,清空该节点的标记。如果有左孩子,访问左孩子,重复此步骤,直至没有左孩子。
  • 标记栈顶元素,访问栈顶元素的右孩子,重复1步骤。如果当前栈顶元素被标记过则打印栈顶元素并出栈,设置指针为空。
  • 当栈为空且指针为空则遍历结束。

BTree.h

#ifndef _BTREE_H_
#define _BTREE_H_

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef char BTDataType;
typedef struct BinaryTreeNode 
{ 
	BTDataType _Bdata;    
	struct BinaryTreeNode* _left;    
	struct BinaryTreeNode* _right; 
}BTNode;
typedef BTNode* DataType;
typedef struct QueueNode
{
	DataType _Qdata;
	struct QueueNode* _next;
}QueueNode;
typedef struct Queue
{
	QueueNode* _front; // 队头
	QueueNode* _rear;  // 队尾
}Queue;
typedef BTNode* STDataType;
typedef struct Stack 
{
	STDataType* _a;
	int _top;       // 栈顶
	int _capacity;  // 容量 
}Stack;
void StackInit(Stack* ps, BTNode *test);
void StackDestory(Stack* ps);
void StackPush(Stack* ps, STDataType x); 
void StackPop(Stack* ps); 
STDataType StackTop(Stack* ps); 
int StackEmpty(Stack* ps); 
int StackSize(Stack* ps);

// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树 
BTNode* BinaryTreeCreate(BTDataType* a);
void BinaryTreeDestory(BTNode** root);

int BinaryTreeSize(BTNode* root); 
int BinaryTreeLeafSize(BTNode* root); 
int BinaryTreeLevelKSize(BTNode* root, int k);

BTNode* BinaryTreeFind(BTNode* root, BTDataType x);
// 遍历 
void BinaryTreePrevOrder(BTNode* root); 
void BinaryTreeInOrder(BTNode* root); 
void BinaryTreePostOrder(BTNode* root);

void QueueInit(Queue *que, BTNode *test);
void QueuePush(Queue *pq, BTNode *node);
void BinaryTreeLevelOrder(BTNode* root);
// 非递归遍历 
// 层序遍历 
void BinaryTreeLevelOrder(BTNode* root); 
// 判断二叉树是否是完全二叉树 
int BinaryTreeComplete(BTNode* root);

void BinaryTreePrevOrderNonR(BTNode* root); 
void BinaryTreeInOrderNonR(BTNode* root); 
void BinaryTreePostOrderNonR(BTNode* root);

#endif /*_BTREE_H_*/

BTree.c

#include"BTree.h"

// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树 
BTNode* BinaryTreeCreate(BTDataType* a)
{
	static int i = 0;
	if (a[i] == '#')
	{
		i++;
		return NULL;
	}
	else
	{
		BTNode *node = (BTNode*)malloc(sizeof(BTNode));
		node->_Bdata = a[i];
		i++;
		node->_left = BinaryTreeCreate(a);
		node->_right = BinaryTreeCreate(a);
		return node;
	}
}
void BinaryTreeDestory(BTNode** root)
{
	if ((*root)->_left != NULL)
		BinaryTreeDestory(&(*root)->_left);
	if ((*root)->_right != NULL)
		BinaryTreeDestory(&(*root)->_right);
	free(*root);
}
int BinaryTreeSize(BTNode* root)
{
	int count = 0;
	if (root == NULL)
		count = 0;
	else
		count = 1 + BinaryTreeSize(root->_left) + BinaryTreeSize(root->_right);
	return count;
}
int BinaryTreeLeafSize(BTNode* root)
{
	int count = 0;
	if (root == NULL)
		count = 0;
	else if (root->_left == NULL&&root->_right == NULL)
		count = 1;
	else
		count = BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right);
	return count;
}
int BinaryTreeLevelKSize(BTNode* root, int k)//计算第k层结点的个数
{
	int count = 0;
	if (root == NULL)
		count = 0;
	else if (k == 1)
		count = 1;
	else
		count = BinaryTreeLevelKSize(root->_left, k - 1) + BinaryTreeLevelKSize(root->_right, k - 1);
	return count;
}
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
	static BTNode* bn = NULL;
	if (root->_Bdata == x)
	{
		bn = root;
		return root;
	}
	if (root->_left != NULL)
		BinaryTreeFind(root->_left, x);
	if (root->_right != NULL)
		BinaryTreeFind(root->_right, x);
	return bn;
}
// 遍历 
void BinaryTreePrevOrder(BTNode* root)
{
	if (root != NULL)
	{
		printf("%c", root->_Bdata);
		BinaryTreePrevOrder(root->_left);
		BinaryTreePrevOrder(root->_right);
	}
}
void BinaryTreeInOrder(BTNode* root)
{
	if (root != NULL)
	{
		BinaryTreeInOrder(root->_left);
		printf("%c", root->_Bdata);
		BinaryTreeInOrder(root->_right);
	}
}
void BinaryTreePostOrder(BTNode* root)
{
	if (root != NULL)
	{
		BinaryTreePostOrder(root->_left);
		BinaryTreePostOrder(root->_right);
		printf("%c", root->_Bdata);
	}
}
void QueueInit(Queue *que, BTNode *test)
{
	QueueNode *node = (QueueNode*)malloc(sizeof(QueueNode));
	node->_Qdata = test;
	node->_next = NULL;
	que->_front = que->_rear = node;
}
void QueuePush(Queue *pq, BTNode *node)
{
	QueueNode *Qnode = (QueueNode*)malloc(sizeof(QueueNode));
	pq->_rear->_next = Qnode;
	Qnode->_next = NULL;
	Qnode->_Qdata = node;
	pq->_rear = pq->_rear->_next;
}
// 层序遍历 
void BinaryTreeLevelOrder(BTNode* root)
{
	Queue *pq = (Queue*)malloc(sizeof(Queue));
	QueueInit(pq, root);
	while (pq->_front != NULL)
	{
		if (pq->_front->_Qdata->_left != NULL)
			QueuePush(pq, pq->_front->_Qdata->_left);
		if (pq->_front->_Qdata->_right != NULL)
			QueuePush(pq, pq->_front->_Qdata->_right);
		printf("%c", pq->_front->_Qdata->_Bdata);
		QueueNode *pt = pq->_front;
		pq->_front = pq->_front->_next;
		free(pt);
	}
	printf("\n");
}
// 判断二叉树是否是完全二叉树 
int BinaryTreeComplete(BTNode* root)
{
	Queue *pq = (Queue*)malloc(sizeof(Queue));
	QueueInit(pq, root);
	int key = 0;
	while (pq->_front != NULL)
	{
		if (pq->_front->_Qdata->_left == NULL&&pq->_front->_Qdata->_right != NULL)
			return 0;
		if (key && (pq->_front->_Qdata->_left != NULL || pq->_front->_Qdata->_right != NULL))
			return 0;
		if (pq->_front->_Qdata->_right == NULL)
			key = 1;

		if (pq->_front->_Qdata->_left != NULL)
			QueuePush(pq, pq->_front->_Qdata->_left);
		if (pq->_front->_Qdata->_right != NULL)
			QueuePush(pq, pq->_front->_Qdata->_right);
		QueueNode *pt = pq->_front;
		pq->_front = pq->_front->_next;
		free(pt);
	}
	return 1;
}
void BinaryTreePrevOrderNonR(BTNode* root)
{
	Stack test;
	StackInit(&test, root);
	while (!StackEmpty(&test) || root != NULL)
	{
		printf("%c", root->_Bdata);
		if (root->_right != NULL)
			StackPush(&test, root->_right);
		if (root->_left != NULL)
			root = root->_left;
		else
		{
			root = StackTop(&test);
			StackPop(&test);
		}
	}
	StackDestory(&test);
}
void BinaryTreeInOrderNonR(BTNode* root)
{
	Stack test;
	StackInit(&test, root);
	while (!StackEmpty(&test) || root != NULL)
	{
		while (root != NULL)
		{
			StackPush(&test, root);
			root = root->_left;
		}
		root = StackTop(&test);
		StackPop(&test);
		putchar(root->_Bdata);
		root = root->_right;
	}
	StackDestory(&test);
}
void BinaryTreePostOrderNonR(BTNode* root)
{
	BTNode * cur = root;
	Stack st;		
	int tag[32] = { 0 }; //左孩子遍历标签
	StackInit(&st, cur);
	while (cur || !StackEmpty(&st))
	{
		for (; cur; cur = cur->_left) //类似中序,将左孩子入栈,cur为空时,代表上一个节点的右孩子为空,只有这种情况,才可能进入下面的while
		{
			StackPush(&st, cur); //push操作会导致size+1
			tag[st._top+1] = 0; //由于入栈的是左孩子,所以这里的左孩子遍历标签置0
		}
		//只要上面的for执行过哪怕一次循环(右孩子不为空),这个while的后半部分条件都不可能满足
		while (!StackEmpty(&st) && tag[st._top+1] == 1) //左孩子还没遍历完成时,不能进入打印
			//所以,这里确保了只有左右子树都遍历完成时,才会进入这个while
		{
			cur = StackTop(&st);
			putchar(cur->_Bdata); //打印根
			StackPop(&st); //pop操作会导致size-1
			cur = NULL; //为了循环正常跳出
		}
		if (!StackEmpty(&st))
		{
			tag[st._top+1] = 1; //进入这里证明左子树遍历完毕,左子树标签置1
			cur = StackTop(&st)->_right; //进入右子树继续遍历
		}		
	}
	StackDestory(&st);
	/*int bool[26] = { 0 };
	Stack test;
	StackInit(&test, root);
	while (!StackEmpty(&test) || root != NULL)
	{
		while (root != NULL)
		{
			if (bool[root->_Bdata - 'A'] == 0)
			{
				StackPush(&test, root);
				bool[root->_Bdata - 'A'] = 1;
			}
			if (root->_right != NULL)
			{
				if (bool[root->_right->_Bdata - 'A'] == 0)
				{
					StackPush(&test, root->_right);
					bool[root->_right->_Bdata - 'A'] = 1;
				}
			}
			if (root->_left != NULL&&bool[root->_left->_Bdata - 'A'] == 1)
				break;
			root = root->_left;
		}
		root = StackTop(&test);
		if (root->_left != NULL&&bool[root->_left->_Bdata - 'A'] == 0)
			continue;
		if (root->_right == NULL||bool[root->_right->_Bdata - 'A'] == 1)
		{
			StackPop(&test);
			putchar(root->_Bdata);
			root = StackTop(&test);
		}
		if (root != NULL&&root->_right != NULL&&bool[root->_right->_Bdata - 'A'] == 0)
		{
			root = root->_right;
		}
	}
	StackDestory(&test);*/
}
void StackInit(Stack* ps, BTNode *test)
{
	int size = BinaryTreeSize(test);
	ps->_a = (STDataType*)malloc(size*sizeof(STDataType));
	ps->_capacity = size;
	ps->_top = -1;
}
void StackDestory(Stack* ps)
{
	free(ps->_a);
	ps->_capacity = 0;
	ps->_top = -1;
}
void StackPush(Stack* ps, STDataType x)
{
	ps->_top++;
	ps->_a[ps->_top] = x;
}
void StackPop(Stack* ps)
{
	if (ps->_top > -1)
		ps->_top--;
}
STDataType StackTop(Stack* ps)
{
	if (ps->_top == -1)
		return NULL;
	return ps->_a[ps->_top];
}
int StackEmpty(Stack* ps)
{
	if (ps->_top == -1)
		return 1;
	return 0;
}
int StackSize(Stack* ps)
{
	return ps->_top + 1;
}

main.c

#include"BTree.h"

int main()
{
	BTNode *test = BinaryTreeCreate("ABDF####CE#GH##I#J###");
	printf("%d\n", BinaryTreeSize(test));
	printf("%d\n", BinaryTreeLeafSize(test));
	//printf("%d\n", BinaryTreeLeve1KSize(test,5));
	printf("%p\n", BinaryTreeFind(test, 'D'));
	BinaryTreePrevOrder(test);
	printf("\n");
	BinaryTreePrevOrderNonR(test);
	printf("\n");
	BinaryTreeInOrder(test);
	printf("\n");
	BinaryTreeInOrderNonR(test);
	printf("\n");
	BinaryTreePostOrder(test);
	printf("\n");
	BinaryTreePostOrderNonR(test);
	printf("\n");
	BinaryTreeLevelOrder(test);
	printf("%d\n", BinaryTreeComplete(test));
	printf("%d\n", BinaryTreeLevelKSize(test, 7));
	BinaryTreeDestory(&test);
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值