数据结构(C语言实现) - 二叉树的基本操作(建立,遍历,结点数,叶子结点数,高度,按树状打印,输出叶子结点等)

通常,对二叉树的操作都是利用二叉链表进行的。

二叉链表:包括三个域-数据域,左孩子,右孩子的结点结构的二叉树存储结构。

二叉链表的存储结构如下:

typedef char DataType;
 
typedef struct node		/*二叉树的存储结构*/ 
{
	DataType data;
 	struct node *Lchild;
 	struct node *Rchild;
}BiTNode,*BiTree;

二叉树的基本操作包括:建立,递归遍历,求结点数,求叶子结点数,输出叶子结点,求二叉树的高度,求结点的双亲,按树状打印等等。 完整代码如下:

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

typedef char DataType;
 
typedef struct node		/*二叉树的存储结构*/ 
{
	DataType data;
 	struct node *Lchild;
 	struct node *Rchild;
}BiTNode,*BiTree;

int Count1=0;	/*统计结点数目的全局变量*/

int Count2=0;	/*统计叶子结点数目的全局变量*/ 

int depth = 0;	/*记录当前求得的最大层次*/ 

BiTNode *Create_BiTree();	/*先序建立二叉树*/	

void  PreOrder(BiTree root);	/*先序遍历二叉树*/

void InOrder(BiTree root);	 /*中序遍历二叉树*/

void PostOrder(BiTree root);	 /*后序遍历二叉树*/

void PreOrder_CalNode(BiTree root);		/*统计二叉树的结点*/

void InOrder_PrintLeaf(BiTree root); 	/*输出二叉树的叶子结点*/

void PostOrder_CalLeaf(BiTree root);	/*方法1-统计叶子结点的数目*/

int CalLeaf(BiTree root);	/*方法2-统计叶子结点的数目*/

void TreeDepth(BiTree root,int h);	/*方法1-求二叉树的高度*/

int PostOrder_TreeDepth(BiTree root);	/*方法2-求二叉树的高度*/

BiTree Parent(BiTree root,BiTree current);	/*求二叉树中某个结点的双亲*/ 

void PrintTree(BiTree root,int h);		/*按树状打印二叉树*/ 
 
int main()
{
	BiTree root;
	/*-----------------二叉树的建立-----------------*/ 
	printf("请输入先序二叉树序列(# = NULL):"); 
	root = Create_BiTree();
	
	/*-----------------二叉树的递归遍历---------------*/ 
	printf("\n先序递归遍历如下:");
	PreOrder(root);
	printf("\n\n中序递归遍历如下:");
	InOrder(root);
	printf("\n\n后序递归遍历如下:");
	PostOrder(root);
	printf("\n");
	
	/*-----------先序遍历统计二叉树中的结点数---------*/ 
	PreOrder_CalNode(root);
	printf("\n二叉树的结点数是:%d\n",Count1);
	
	/*-----------中序遍历输出二叉树的叶子结点---------*/ 
	printf("\n二叉树的叶子结点是:");
	InOrder_PrintLeaf(root);
	printf("\n");
	
	/*----------后序遍历统计二叉树的叶子结点数---------*/
	PostOrder_CalLeaf(root);
	printf("\n二叉树的叶子结点数是:%d\n",Count2); 
	
	/*----------遍历计算二叉树的高度(层次数)---------*/
	int h=1; /*h为root所在的层次,初始值为1*/
	TreeDepth(root,h);
	printf("\n二叉树的高度是:%d\n",depth);
	
	/*-----------------求某结点的双亲----------------*/
	
	
	/*-----------------按树状打印二叉树--------------*/
	h = 1;
	printf("\n二叉树的树状打印如下:\n\n");
	PrintTree(root,h);
	
	return 0;
}

BiTNode *Create_BiTree()		/*先序建立二叉树*/
{
	DataType ch;
    BiTree root;
    scanf("%c",&ch);
    if(ch=='#')		root=NULL;
    else{
        root = (BiTree)malloc(sizeof(BiTNode));
        root->data = ch;
        root->Lchild = Create_BiTree();
        root->Rchild = Create_BiTree();
    }
    return root;
}

void  PreOrder(BiTree root)	/*先序遍历二叉树*/
{
	if(root){
		printf("%c",root->data);	/*访问根节点数据*/ 
		PreOrder(root->Lchild);		/*先序访问左子树*/ 
		PreOrder(root->Rchild);		/*先序访问右子树*/ 
	}
}

void InOrder(BiTree root) /*中序遍历二叉树*/
{
	if(root){
		InOrder(root->Lchild);		/*中序访问左子树*/ 
		printf("%c",root->data);	/*访问根节点数据*/ 
		InOrder(root->Rchild);		/*中序访问右子树*/ 
	}
}

void PostOrder(BiTree root) /*中序遍历二叉树*/
{
	if(root){
		PostOrder(root->Lchild);		/*后序访问左子树*/  
		PostOrder(root->Rchild);		/*后序访问右子树*/
		printf("%c",root->data);	/*访问根节点数据*/
	}
}

void PreOrder_CalNode(BiTree root)		/*统计二叉树的结点*/
{
	if(root)
	{
		Count1++;
		PreOrder_CalNode(root->Lchild);
		PreOrder_CalNode(root->Rchild);
	}
}

void InOrder_PrintLeaf(BiTree root) 	/*输出二叉树的叶子结点*/
{
	if(root){
		InOrder_PrintLeaf(root->Lchild);
		if(root->Lchild == NULL  &&  root->Rchild == NULL){
			printf("%c ",root->data);		/*输出叶子结点*/ 
		}
		InOrder_PrintLeaf(root->Rchild);
	}
}

void PostOrder_CalLeaf(BiTree root)		/*方法1-统计叶子结点的数目*/ 
{
	if(root){
		PostOrder_CalLeaf(root->Lchild);
		PostOrder_CalLeaf(root->Rchild);
		if(root->Lchild == NULL  &&  root->Rchild == NULL){
			Count2++;		/*统计叶子结点*/ 
		}
	}
}

int CalLeaf(BiTree root)	/*方法2-统计叶子结点的数目*/
{
	int nl,nr;		/*nl,nr分别统计左右子树的叶子结点数目*/ 
	if(root==NULL) return 0;
	if(root->Lchild==NULL && root->Rchild==NULL) return 1;
	nl = CalLeaf(root->Lchild);		/*递归求左子树的叶子数*/
	nr = CalLeaf(root->Rchild); 	/*递归求右子树的叶子数*/ 
}

void TreeDepth(BiTree root,int h)	/*方法1-求二叉树的高度*/
{
	if(root){
		if(h>depth) depth = h;		/*当前结点层次大于depth,更新*/
		TreeDepth(root->Lchild,h+1);	/*遍历左子树,子树根层次为h+1*/ 
		TreeDepth(root->Rchild,h+1);	/*遍历右子树,子树根层次为h+1*/ 
	}
}

int PostOrder_TreeDepth(BiTree root)	/*方法2-求二叉树的高度*/
{
	int hl,hr,h;
	if(root==NULL) return 0;
	else {
		hl = PostOrder_TreeDepth(root->Lchild); /*递归求左子树的高度*/ 
		hr = PostOrder_TreeDepth(root->Rchild);	/*递归求右子树的高度*/
		h = (hl > hr ? hl : hr) + 1;  /*计算树的高度*/
		return h; 
	}
}

BiTree Parent(BiTree root,BiTree current)	/*求二叉树中某个结点的双亲*/
{
	BiTree p;
	if(root==NULL) return NULL;
	if(root->Lchild==current || root->Rchild==current)
	return root;						/*  *root即为current的双亲*/
	p=Parent(root->Lchild,current);		/*递归在左子树中查找*/
	if(p!=NULL) return p;
	else return(Parent(root->Rchild,current));	/*递归在右子树中查找*/ 
	
} 

void PrintTree(BiTree root,int h)		/*按树状打印二叉树*/
{
	if(root==NULL) return;
	PrintTree(root->Rchild,h+1);	/*先序打印右子树*/
	for(int i=0;i<h;i++)  printf("  ");
	printf("%c\n",root->data);		/*输出结点*/
	PrintTree(root->Lchild,h+1);	/*先序打印右子树*/ 
}		
运行结果如下:



在C语言中,我们可以使用构体来代表二叉树的节点,并通过指针连接相邻的节点。以下是基本操作实现: ```c #include <stdio.h> #include <stdlib.h> // 定义二叉树节点构体 typedef struct TreeNode { int val; struct TreeNode* left; struct TreeNode* right; } TreeNode; // 创建新节点并插入值 TreeNode* createNode(int val) { TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode)); newNode->val = val; newNode->left = NULL; newNode->right = NULL; return newNode; } // 先序遍历(根--右) void preorderTraversal(TreeNode* root, char* output) { if (root != NULL) { output[0] = root->val + '0'; output++; preorderTraversal(root->left, output); preorderTraversal(root->right, output); } } // 中序遍历(左--右) void inorderTraversal(TreeNode* root, char* output) { if (root != NULL) { inorderTraversal(root->left, output); output[0] = root->val + '0'; output++; inorderTraversal(root->right, output); } } // 后序遍历(左--根) void postorderTraversal(TreeNode* root, char* output) { if (root != NULL) { postorderTraversal(root->left, output); postorderTraversal(root->right, output); output[0] = root->val + '0'; output++; } } // 层次遍历(广度优先搜索) void levelOrderTraversal(TreeNode* root, int depth, char* output) { if (root == NULL) return; int i = 0; queue<TreeNode*> q; q.push(root); while (!q.empty()) { TreeNode* node = q.front(); q.pop(); output[i++] = node->val + '0'; if (node->left) q.push(node->left); if (node->right) q.push(node->right); printf("%d ", output[i - 1]); } printf("\n"); } int main() { // 示例:构建一颗简单的二叉树 TreeNode* root = createNode(1); root->left = createNode(2); root->right = createNode(3); root->left->left = createNode(4); root->left->right = createNode(5); // 初始化输出数组 char output[100]; // 执行遍历操作 printf("Preorder Traversal: "); preorderTraversal(root, output); printf("\nInorder Traversal: "); inorderTraversal(root, output); printf("\nPostorder Traversal: "); postorderTraversal(root, output); printf("\nLevel Order Traversal: "); levelOrderTraversal(root, 0, output); // 计算深度,这里假设二叉树的深度递归计算 int treeDepth = getTreeDepth(root); // 自行实现此函数 printf("\nTree Depth: %d\n", treeDepth); return 0; } ``` 在这个示例中,我们首先创建了一个二叉树实例,然后实现了四种遍历方式的函数。`getTreeDepth`函数需要你自己实现,通常会使用递归或者迭代的方式来计算二叉树的最大层级。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值