二叉树的实现(C语言)

二叉树是采用链表的结构来实现

1.建立头文件


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


// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* Creattree(BTDataType* a,  int* pi);



// 二叉树销毁
void BinaryTreeDestroy(BTNode* root);
// 二叉树节点个数
int TreeSize(BTNode* root);
// 二叉树叶子节点个数
int TreeLeafSize(BTNode* root);
// 二叉树第k层节点个数
int TreeKLevel(BTNode* root, int k);
// 二叉树查找值为x的节点
BTNode* TreeFind(BTNode* root, BTDataType x);

int TreeHeight(BTNode* root);  //树的深度

// 二叉树前序遍历 
void  PreOrder(BTNode* root);
// 二叉树中序遍历
void InOrder(BTNode* root);
// 二叉树后序遍历
void afOrder(BTNode* root);



// 层序遍历
void TreeLevelOrder(BTNode* root);
// 判断二叉树是否是完全二叉树
int BinaryTreeComplete(BTNode* root);

2.用前序遍历来建立树

BTNode* Creattree(BTDataType* a, int* pi)
{
	if (a[*pi] == '#')
	{
		(*pi)++;
		return  NULL;
	}
	BTNode* root = (BTNode*)malloc(sizeof(BTNode));
	if (root == NULL)
	{
		perror("malloc fail");
		return  NULL;
	}
	root->data = a[*pi];
	(*pi)++;
	root->left = Creattree(a, pi);
	root->right = Creattree(a, pi);
	return root;
}

如果数组a【*pi】不为空,就开辟空间来存储a【*pi】,同时(*pi)++。然后依次根据左子树,右子树来递归建立树,遇到空时返回。

3.树的销毁


void BinaryTreeDestroy(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}

	BinaryTreeDestroy(root->left);
	BinaryTreeDestroy(root->right);
	free(root);
}

由于树是链表结构,所以用递归来依次释放节点。

4.前序遍历

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

	PreOrder(root->left);

	PreOrder(root->right);

}

在访问左右子树前先打印该节点

5.中序遍历

// 二叉树中序遍历
void  InOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	InOrder(root->left);

	printf("%d ", root->data);

	InOrder(root->right);
}

6.后序遍历

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

7.二叉树节点个数

int TreeSize(BTNode* root)           // 二叉树节点个数
{
	return root == NULL ? 0 :
		TreeSize(root->left) + TreeSize(root->right) + 1;
}

依然采用递归来计算节点个数

8.叶子结点个数

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

只有遇到叶子节点的时候才会返回1,这样左右子树层层返回相加,最后计算出叶子节点个数。

9.树的深度

int TreeHeight(BTNode* root)      //树的深度
{
	if (root == NULL)
		return 0;
	int lh = TreeHeight(root->left);
	int rh = TreeHeight(root->right);
	return lh > rh ? lh + 1 : rh + 1;
}

用lh和rh来比较大小,这样更深一层的树就会显示出来,包含了浅一层的树。

10.第k层的节点个数

// 第K层节点个数 
int TreeKLevel(BTNode* root, int k)
{
	assert(k > 0);
	if (root == NULL)
		return 0;
	if (k == 1)
		return 1;
	// 转换成求子树第k-1层
	return TreeKLevel(root->left, k - 1)
		+ TreeKLevel(root->right, k - 1);
}

11.返回查找节点的位置

// 返回x所在的节点     // 二叉树查找值为x的节点
BTNode* TreeFind(BTNode* root, BTDataType x)
{
	BTNode* lret, * rret;
	if (root == NULL)
		return NULL;
	if (root->data == x)
		return root;
	// 先去左树找
	lret = TreeFind(root->left, x);
	if (lret)
		return lret;
	// 左树没有找到,再到右树找
	rret = TreeFind(root->right, x);
	if (rret)
		return rret;
	return NULL;
}

12.二叉树的层序遍历


void TreeLevelOrder(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);
	}
	printf("\n");

	QueueDestroy(&q);
}

其中包含了队列的使用方式

13.判断是不是完全二叉树


// 判断二叉树是否是完全二叉树
int BinaryTreeComplete(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	if (root)
		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)
		{
			QueueDestroy(&q);
			return false;
		}
	}
	QueueDestroy(&q);
	return true;
}

也是依次层序遍历,然后在最后一层判断遇到空后是不是一直为空

14.测试

BTNode* CreateTree()
{
	BTNode* n1 = (BTNode*)malloc(sizeof(BTNode));
	assert(n1);
	BTNode* n2 = (BTNode*)malloc(sizeof(BTNode));
	assert(n2);
	BTNode* n3 = (BTNode*)malloc(sizeof(BTNode));
	assert(n3);
	BTNode* n4 = (BTNode*)malloc(sizeof(BTNode));
	assert(n4);
	BTNode* n5 = (BTNode*)malloc(sizeof(BTNode));
	assert(n5);
	BTNode* n6 = (BTNode*)malloc(sizeof(BTNode));
	assert(n6);
	BTNode* n7 = (BTNode*)malloc(sizeof(BTNode));
	assert(n7);

	n1->data = 1;
	n2->data = 2;
	n3->data = 3;
	n4->data = 4;
	n5->data = 5;
	n6->data = 6;
	n7->data = 7;

	n1->left = n2;
	n1->right = n4;
	n2->left = n3;
	n2->right = NULL;
	n4->left = n5;
	//n4->right = n6;
	n4->right = NULL;
	n3->left = NULL;
	n3->right = NULL;
	n5->left = NULL;
	n5->right = NULL;
	//n6->left = NULL;
	//n6->right = NULL;

	//n3->right = n7;
	n2->right = n7;
	n7->left = NULL;
	n7->right = NULL;

	return n1;
}



int main()
{
	BTNode* root = CreateTree();
	PreOrder(root);
	printf("\n");

	InOrder(root);
	printf("\n");

	//count = 0;
	//TreeSize(root);
	//printf("Tree size:%d\n", count);

	//count = 0;
	//TreeSize(root);
	//printf("Tree size:%d\n", count);

	printf("Tree size:%d\n", TreeSize(root));
	printf("Tree size:%d\n", TreeSize(root));
	printf("Tree size:%d\n", TreeSize(root));

	printf("Tree Leaf size:%d\n", TreeLeafSize(root));
	printf("Tree Height:%d\n", TreeHeight(root));
	printf("Tree K Level:%d\n", TreeKLevel(root, 3));
	printf("Tree Find:%p\n", TreeFind(root, 8));

	BTNode* ret = TreeFind(root, 7);
	ret->data *= 10;

	PreOrder(root);
	printf("\n");

	BinaryTreeDestroy(root);
	root = NULL;

	return 0;
}

测试结果

二叉树的实现(C语言)_第1张图片

 

你可能感兴趣的:(数据结构(C),c语言,数据结构,链表)