二叉树的链式存储及常见操作

一:关于二叉树的链式存储请参考:https://blog.csdn.net/qq_38158479/article/details/104107974
关于二叉树的遍历请参考:https://blog.csdn.net/qq_38158479/article/details/104113648

二:代码实现:

#include"BiTree.h"

int main(void)
{
	int nodecount, lefa, depth;

	BiNode* P = NULL;
		
	P=(BiNode*)malloc(sizeof(BiNode));

	//printf("请输入根结点:");
	CreatBinaryTree_test(P);

	printf("前序遍历的结果为:");
	PreOrderTraverse1(P);
	printf("\n");

	printf("中序遍历的结果为:");
	PreOrderTraverse2(P);
	printf("\n");
   /*
	printf("后序遍历的结果为:");
	PreOrderTraverse3(P);
	printf("\n");
   */
	printf("层序遍历的结果为:");
	PreOrderTraverse4(P);
	printf("\n");

	nodecount = BinaryTreeNodecount(P);
	printf("二叉树的结点个数为:%d\n", nodecount);

	depth = BinaryTreedepth(P);
	printf("二叉树的深度为:%d\n", depth);

	lefa = leafcount(P);
	printf("二叉树的叶子数为:%d\n", lefa);

	system("pause");

	return 0;
}
#include"BiTree.h"

/*创建一个链式二叉树-需要手动输入->输入0代表结点为空*/
int CreatBinaryTree(BiNode* T)
{
	if (T == NULL)
	{
		return 0;
	}

	int k;

	scanf_s("%d",&k,2);

	if (k==0)
	{
		T = NULL;

		return 0;
	}

	T->data = k;

	T->lchild = (BiNode*)malloc(sizeof(BiNode));

	T->rchild = (BiNode*)malloc(sizeof(BiNode));

	printf("左结点:");

	if (CreatBinaryTree(T->lchild) == 0)
	{
		free(T->lchild);

		T->lchild = NULL;
	}
		
	printf("右结点:");

	if (CreatBinaryTree(T->rchild) == 0)
	{
		free(T->rchild);

		T->rchild = NULL;
	}
		
	return 1;
}

/*测试版创建一个链式二叉树->不需要手动输入*/
int CreatBinaryTree_test(BiNode* T)
{
	static int BinaryTreeIndex = 0;

	int k;

	int nodename[15] = { 1,2,4,0,0,5,0,0,3,6,0,0,7,0,0 };//二叉树结构

	if (T == NULL)
	{
		return 0;
	}	
	k = nodename[BinaryTreeIndex++];//把提前写好的二叉树结点数据赋给k

	if (k == 0)
	{
		T = NULL;

		return 0;
	}

	T->data = k;

	T->lchild = (BiNode*)malloc(sizeof(BiNode));

	T->rchild = (BiNode*)malloc(sizeof(BiNode));

	if (CreatBinaryTree_test(T->lchild) == 0)
	{
		free(T->lchild);

		T->lchild = NULL;//如果该结点的左孩子没有则该节点的T->lchild(指针域)指向NULL
	}

	if (CreatBinaryTree_test(T->rchild) == 0)
	{
		free(T->rchild);

		T->rchild = NULL;//如果该结点的右孩子没有则该节点的T->rchild(指针域)指向NULL
	}

	return 1;
}

/*前序遍历-根->左->右*/
void PreOrderTraverse1(BiNode* T)
{
	if (T == NULL)
	{
		return;
	}
	printf("%d\t", T->data);

	PreOrderTraverse1(T->lchild);

	PreOrderTraverse1(T->rchild);
}

/*中序遍历-左->根->右*/
void PreOrderTraverse2(BiNode* T)
{
	if (T == NULL)
	{
		return;
	}
	PreOrderTraverse2(T->lchild);

	printf("%d\t", T->data);

	PreOrderTraverse2(T->rchild);
}

/*后序遍历-左->右->根*/
void PreOrderTraverse3(BiNode* T)
{
	if (T == NULL)
	{
		return;
	}
	PreOrderTraverse3(T->lchild);

	PreOrderTraverse3(T->rchild);

	printf("%d\t", T->data);
}

/*层序遍历->从上到下从左到右*/
void PreOrderTraverse4(BiNode* T)
{
	return;
}

/*计算链式二叉树结点个数*/
int BinaryTreeNodecount(BiNode* T)
{
	
	if (T == NULL)
	{
		return 0;
	}
	else
	{
		return BinaryTreeNodecount(T->lchild) + BinaryTreeNodecount(T->rchild) + 1;
	}
	
}

/*计算链式二叉树的深度*/
int BinaryTreedepth(BiNode* T)
{
	int left = 0;

	int right = 0;

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

	left = BinaryTreedepth(T->lchild);

	right = BinaryTreedepth(T->rchild);

	return 1 + (left > right ? left : right);
}

/*计算链式二叉树的叶子总数*/
int leafcount(BiNode* T)
{
	if (T == NULL)
	{
		return 0;
	}
	if (T->lchild == NULL && T->rchild == NULL)
	{
		return 1;
	}
	else
	{
		return leafcount(T->lchild) + leafcount(T->rchild);
	}
}
#ifndef _BiTree_h
#define _BiTree_h

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

/*二叉链表的结点结构*/
typedef struct BiNode
{
	struct BiNode* lchild;/*左孩子指针*/

	struct BiNode* rchild;/*右孩子指针*/

	int data;/*数据域*/
}BiNode;

/*二叉树链表结构*/
typedef struct BinaryTree
{
	int count; /*二叉树结点个数*/

	int depth;  /*二叉树深度/高度*/

	struct BiNode* p;

}BinaryTree;

extern int CreatBinaryTree(BiNode* T);
extern int CreatBinaryTree_test(BiNode* T);
extern void PreOrderTraverse1(BiNode* T);
extern void PreOrderTraverse2(BiNode* T);
extern void PreOrderTraverse3(BiNode* T);
extern void PreOrderTraverse4(BiNode* T);
extern int BinaryTreeNodecount(BiNode* T);
extern int BinaryTreedepth(BiNode* T);
extern int leafcount(BiNode* T);

#endif // !_BiTree_h

//代码测试结果:
在这里插入图片描述
代码说明:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

关于层序遍历代码的补充:
(利用到了队列先进先出的性质,队列节点的结构当中数据域类型为树的节点类型)

linkqueue initseqQueue()  //队列初始化
{
	linkqueue q = NULL;
	linklist p = NULL;

	q = (linkqueue)malloc(sizeof(linkqueue_node));
	p = (linklist)malloc(sizeof(linknode));

	if (q == NULL || p == NULL)
	{
		return NULL;
	}

	q->front = p;
	q->rear = p;

	p->node = NULL;
	p->next = NULL;

	return q;
}

void inseqQueue(linkqueue top, BiNode* T) //进队
{
	linklist t = NULL;
	t = (linklist)malloc(sizeof(linknode));

	t->node = T;
	t->next = NULL;

	top->rear->next = t;
	top->rear = t;
}

BiNode* outseqQueue(linkqueue top)
{
	linklist t = NULL;
	BiNode *T = NULL;

	t = top->front;
	top->front = top->front->next;
	T = top->front->node;

	free(t);
	return T;
}

int seqQueue_is_empty(linkqueue top)
{
	return (top->front == top->rear) ? 1 : 0;
}
//链式队列节点数据类型
typedef struct node
{
	struct BiNode* node; //这里进队出队的数据元素类型为数的结点类型
	struct node* next;
}*linklist, linknode;
//链式队列数据类型
typedef struct queue
{
	linklist front, rear;
}*linkqueue, linkqueue_node;
/*层序遍历->从上到下从左到右*/
void PreOrderTraverse4(BiNode* T)
{
	linkqueue queue;

	queue=initseqQueue();//创建一个空的队列

	inseqQueue(queue,T);//根结点进队

	while (!seqQueue_is_empty(queue))//在队列不为空的情况下进行遍历
	{
		BiNode* p = outseqQueue(queue);//根节点出队

		printf("%d\t", p->data);

		if (p->lchild != NULL)
		{
			inseqQueue(queue, p->lchild);//左孩子进队
		}
		if (p->rchild != NULL)
		{
			inseqQueue(queue, p->rchild);//右孩子进队
		}

	}
	return;
}

//测试结果
在这里插入图片描述

发布了150 篇原创文章 · 获赞 81 · 访问量 6461

猜你喜欢

转载自blog.csdn.net/qq_38158479/article/details/104137881