【数据结构】【C语言】二叉链表的相关操作

以二叉链表为存储结构,设计实现二叉树的建树、先中后三种非递归遍历算法、树的层次遍历,并统计二叉树中度为1、2的结点个数和叶子结点的个数,计算出二叉树的深度。

#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#define MAX_SIZE 1000
typedef int Data;


//树的结构体
typedef struct Node
{
	struct Node* left;
	struct Node* right;
	Data val;
}*LNode, Node;

typedef LNode Status;
//栈的结构体
typedef struct Stack
{
	Status* base;
	Status* top;
	int stacksize;
}Stack;
//队列结构体
typedef struct Queue
{
	Status* base;
	int front;
	int rear;
}Queue;

//初始化栈
void InitStack(Stack* st)
{
	st->base = (Status*)malloc(MAX_SIZE * sizeof(Status));
	st->stacksize = MAX_SIZE;
	st->top = st->base;
}
//入栈
void Push(Stack* st, Status e)
{
	if (st->top - st->base != st->stacksize)
	{
		*st->top = e;
		st->top++;
	}
}
//出栈
void Pop(Stack* st)
{
	if (st->base != st->top)
	{
		st->top--;
	}
}
//返回栈顶元素
Status GetTop(Stack st)
{
	if (st.base != st.top)
		return *--st.top;
}
//判断是否栈空
int StackEmpty(Stack st)
{
	if (st.base == st.top)
		return 1;
	return 0;
}
//初始化队列
void InitQueue(Queue* qu)
{
	qu->base = (Status*)malloc(MAX_SIZE * sizeof(Status));
	qu->front = 0;
	qu->rear = 0;
}//入队
void EnQueue(Queue* qu, Status e)
{
	if ((qu->rear + 1) % MAX_SIZE != qu->front)
	{
		qu->base[qu->rear] = e;
		qu->rear = (qu->rear + 1) % MAX_SIZE;
	}
}
//出队
void DeQueue(Queue* qu)
{
	if (qu->front != qu->rear)
	{
		qu->front = (qu->front + 1) % MAX_SIZE;
	}
}
//返回队首元素
Status GetHead(Queue qu)
{
	if (qu.front != qu.rear)
	{
		return qu.base[qu.front];
	}
	return NULL;
}
//判断队列是否为空
int QueueEmpty(Queue qu)
{
	if (qu.front != qu.rear)
		return 1;
	return 0;
}
//非递归算法初始化树,先序遍历创建树
void InitTree(LNode* tree)
{
	Data val;
	scanf_s("%d", &val);
	LNode root;
	if (val == -1)
	{
		root = NULL;
	}
	else
	{
		root = (LNode)malloc(sizeof(Node));
		root->val = val;
		InitTree(&root->left);
		InitTree(&root->right);
	}
	*tree = root;
}
//非递归先序遍历
void PreOrderTraverse(LNode root)
{
	Stack st;
	InitStack(&st);
	LNode top = root;
	while (!StackEmpty(st) || top)
	{
		while (top)
		{
			printf("%d ", top->val);
			Push(&st, top);
			top = top->left;
		}
		if (!StackEmpty(st))
		{
			top = GetTop(st);
			Pop(&st);
			top = top->right;
		}
	}
	printf("\n");
}
//非递归中序遍历
void InOrderTraverse(LNode root)
{
	Stack st;
	InitStack(&st);
	LNode top = root;
	while (!StackEmpty(st) || top)
	{
		while (top)
		{
			Push(&st, top);
			top = top->left;
		}
		if (!StackEmpty(st))
		{
			top = GetTop(st);
			Pop(&st);
			printf("%d ", top->val);
			top = top->right;
		}
	}
	printf("\n");
}
//非递归后序遍历
void PostOrderTraverse(LNode root)
{
	Stack st, st2;
	InitStack(&st);
	InitStack(&st2);
	LNode top = root;
	while (!StackEmpty(st) || top)
	{
		while (top)
		{
			Push(&st, top);
			Push(&st2, top);
			top = top->right;
		}
		if (!StackEmpty(st))
		{
			top = GetTop(st);
			Pop(&st);
			top = top->left;
		}
	}
	while (!StackEmpty(st2))
	{
		top = GetTop(st2);
		printf("%d ", top->val);
		Pop(&st2);
	}
	printf("\n");
}
//二叉树层次遍历
void HierarchicalTraversal(LNode root)
{
	LNode Head = root;
	Queue qu;
	InitQueue(&qu);
	EnQueue(&qu, Head);
	while (!QueueEmpty(qu) || Head)
	{
		if (Head)
		{
			printf("%d ", Head->val);
			EnQueue(&qu, Head->left);
			EnQueue(&qu, Head->right);

		}
		DeQueue(&qu);
		Head = GetHead(qu);
	}
	printf("\n");
}
//返回树的深度
int Depth(LNode root)
{
	if (root == NULL)
		return 0;
	else
	{
		int m = Depth(root->left) + 1;
		int n = Depth(root->right) + 1;
		return m > n ? m : n;
	}
}
//得到度分别为0,1,2的数量,z是度为0的数量,o是度为1的数量,t是度为0的数量
void Degree(LNode root, int* z, int* o, int* t)
{
	if (root == NULL)
		return;
	else
	{
		if (root->left != NULL && root->right != NULL)
			(*t)++;
		else if (root->left == NULL && root->right == NULL)
			(*z)++;
		else
			(*o)++;
		Degree(root->left, z, o, t);
		Degree(root->right, z, o, t);
	}
}
//主页面
void test()
{
	LNode root = NULL;
	while (1)
	{
		printf("1.创建二叉树\n");
		printf("2.先序遍历\n");
		printf("3.中序遍历\n");
		printf("4.后序遍历\n");
		printf("5.树的深度\n");
		printf("6.二叉树层次遍历\n");
		printf("7.不同度的节点个数\n");
		int choice;
		scanf_s("%d", &choice);
		switch (choice)
		{
		case 1:
			printf("输入数据:\n");
			InitTree(&root);
			break;
		case 2:
			printf("先序遍历为:\n");
			PreOrderTraverse(root);
			break;
		case 3:
			printf("中序遍历为:\n");
			InOrderTraverse(root);
			break;
		case 4:
			printf("后序遍历为:\n");
			PostOrderTraverse(root);
			break;
		case 5:
			printf("树的深度为:%d\n", Depth(root));
			break;
		case 6:
			printf("二叉树层次遍历为:\n");
			HierarchicalTraversal(root);
			break;
		case 7:
			int z = 0, o = 0, t = 0;
			Degree(root, &z, &o, &t);
			printf("度为1的节点个数为:%d\n", o);
			printf("度为2的节点个数为:%d\n", t);
			printf("叶子节点个数为:%d\n", z);
		}
		system("pause");
		system("cls");
	}
}
int main()
{
	test();
	return 0;
}

实机演示:

简单的创建一个上图的二叉树例子

 先序遍历(非递归)

中序遍历(非递归) 

 后序遍历(非递归)

 

 树的深度

 层次遍历

 不同度的节点个数

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值