数据结构(c语言实现)——完全二叉树链式存储

完全二叉树的构建及链式存储

//完全二叉树
//队列的链式存储
#include <stdio.h>
#include <malloc.h>
#include <string.h>

#define max 51
#define initSize 10


typedef struct
{
	int number[initSize];
	int top;	//线性栈当前位置
}Stack;
struct People
{
	char name[max];
	char ID[max];
};
typedef struct treeNode
{
	People people1;
	struct treeNode* lNext;
	struct treeNode* rNext;
}treeNode , *BiTree;

void initStack(Stack& stack);//初始化栈
bool stackEmpty(Stack stack);//判断是否为空栈
bool stackFull(Stack stack);//判断是否为满栈
bool push(Stack& stack, int number);//入栈
bool pop(Stack& stack, int& number);//出栈



void initTree(BiTree &tree , People peo);//初始化二叉树
void preOrder(BiTree tree , int &i);//先序遍历
void inOrder(BiTree tree , int &i);//中序遍历
void postOrder(BiTree tree, int& i);//后序遍历
void visit(BiTree tree ,int &i );//访问节点
void getStack(Stack& stack, int i);//访问获取指定节点的路径
bool addNode(BiTree &tree , People peo);//添加节点
bool delBiTree(BiTree &tree);//销毁树
void printPeo(People peo);//输出people

int main()
{
	People peo = { "李参政" , "0418" };
	People peo1[6] = { {"李" , "0418"} , {"参" , "0418"} ,{"正" ,"0418"} ,{ "li" , "0418"} ,{"can" ,"0418" } ,{"zheng" ,"0418"} };

	BiTree tree;
	initTree(tree , peo);
	
	for (int j = 0; j < 6; j++)
	{
		addNode(tree, peo1[j]);
	}
	int i = 0;
	printf("i = %d\n", i);
	printf("先序遍历\n");
	preOrder(tree, i);
	printf("********************************************\n");
	//printf("i = %d\n", i);

	i = 0;
	printf("i = %d\n", i);
	printf("中序遍历\n");
	inOrder(tree, i);
	printf("********************************************\n");
	//printf("i = %d\n", i);



	i = 0;
	printf("i = %d\n", i);
	printf("后序遍历\n");
	postOrder(tree, i);
	printf("********************************************\n");
	//printf("i = %d\n", i);
	

	delBiTree(tree);
	return 0;

}

void initTree(BiTree& tree , People peo)//初始化二叉树
{
	tree = (treeNode*)malloc(sizeof(treeNode));//创建根节点
	tree->people1 = peo;//修改根节点数据域
	tree->lNext = NULL;//根节点左孩子置空
	tree->rNext = NULL;//根节点有孩子置空
}

void preOrder(BiTree tree, int& i)//先序遍历
{
	
	if (tree != NULL)
	{
		visit(tree, i);//访问节点父节点
		preOrder(tree->lNext, i);//访问左边子节点
		preOrder(tree->rNext , i);//访问右边子节点

	}
	
}

void inOrder(BiTree tree, int& i)//中序遍历
{
	if (tree != NULL)
	{
		preOrder(tree->lNext, i);//访问左边子节点
		visit(tree, i);//访问节点父节点
		preOrder(tree->rNext, i);//访问右边子节点
	}
	
}
void postOrder(BiTree tree, int& i)//后序遍历
{
	if (tree != NULL)
	{
		preOrder(tree->lNext, i);//访问左边子节点
		preOrder(tree->rNext, i);//访问右边子节点
		visit(tree, i);//访问节点父节点
	}
}
void visit(BiTree tree, int& i)//访问节点
{
	if (tree != NULL)//如果节点非空,节点数加1
	{
		i++;
		printPeo(tree->people1);
		//printf("vist_i = %d\t" ,i);
	}
	else//节点为空,不执行操作
		;
}

bool addNode(BiTree& tree, People peo )//添加节点
{
	int num = 0;
	preOrder(tree ,num);//先序遍历树,获取节点数量
	//printf("num1 = %d\t" ,num);
	treeNode* node = NULL;
	node = tree;//创建参数节点,并将根节点地址赋给参数节点;
	num++;
	//printf("num_change = %d\t" , num);
	int last_number = num - ((int)(num / 2))*2;//last_number = 0则插入节点是根节点的左孩子,last_number = 1则插入节点是其父节点的有孩子
	//printf("lastNum = %d\n", last_number);
	Stack stack;//创建访问父节点路径栈
	initStack(stack);
	int stack_number = num / 2;
 	getStack(stack, stack_number);//获取访问插入节点父节点的路径栈
	while (!stackEmpty(stack))	//访问父节点
	{
		int number = 0;
		pop(stack, number);
		//printf("number = %d\n" ,number);
		if (node != NULL && number == 0 && node->lNext != NULL)
			node = node->lNext;
		if (node != NULL && number == 1 && node->rNext != NULL)
			node = node->rNext;
		//printf("node = %x\n" ,node);
	}

	treeNode* newnode = (treeNode*)malloc(sizeof(treeNode));
	newnode->people1 = peo;
	newnode->lNext = NULL;
	newnode->rNext = NULL;
	//printf("newNode = %x\t" , newnode);
	if (last_number == 0)
	{
		node->lNext = newnode;
	}
	if (last_number == 1)
	{
		node->rNext = newnode;
	}
	//printf("l = %x\t" , node->lNext);
	//printf("r = %x\n" , node->rNext);
	//printf("**********************************************************************\n");
	return true;
}

bool delBiTree(BiTree& tree)//销毁树
{
	//空树
	if (tree == NULL)
		return false;

	//只有根节点的树,直接释放根节点空间销毁树
	if (tree->lNext == NULL && tree->rNext == NULL)
	{
		free(tree);
		return true;
	}

	int num = 0;
	preOrder(tree, num);//遍历树,获取节点数量
	while (num != 0)//从最后节点依次释放节点空间
	{
		treeNode* node = NULL;
		node = tree;
		int last_nuber = num - (int)(num / 2) * 2;//判断最后一个节点是其父节点的左孩子还是右孩子
		Stack stack;
		initStack(stack);
		getStack(stack,num/2 );//获取父节点访问栈
		while (!stackEmpty(stack))//访问其父节点
		{
			int number = 0;
			pop(stack, number);
		
			if (node != NULL && number == 0 && node->lNext != NULL)
				node = node->lNext;
			else if (node != NULL && number == 1 && node->rNext != NULL)
				node = node->rNext;
		}

		//删除最后一个节点
		if (last_nuber == 0)
		{
			free(node->lNext);
			node->lNext = NULL;
		}
		else if (last_nuber == 1)
		{
			free(node->rNext);
			node->rNext = NULL;
		}		
		num--;//节点数减一
	}
	return true;
}
//获取第i个节点的访问路径,
void getStack(Stack &stack ,int i)
{
	int num = i;
	int quo = 0;
	while (num/2 != 0)
	{
		quo = num / 2;
		int ele = num - quo * 2;
		push(stack, ele);
		num = num / 2;
	}

}

void printPeo(People peo)//输出people
{
	printf("name = %s\n", peo.name);
	printf("ID = %s\n", peo.ID);
	printf("-------------------------------\n");
}

void initStack(Stack& stack)//初始化栈
{
	stack.top = 0;//指向栈的第一个空间,此时栈为空栈
}

bool stackEmpty(Stack stack)//判断是否为空栈
{
	if (stack.top == 0)
		return true;
	else
		return false;
}
bool stackFull(Stack stack)//判断是否为满栈
{
	if (stack.top >= initSize)
		return true;
	else
		return false;
}
bool push(Stack& stack, int number)//入栈
{
	//栈满
	if (stackFull(stack))
		return false;
	int top = stack.top;
	stack.number[top] = number;//元素入栈
	++stack.top;//栈顶向上移
	return true;
}
bool pop(Stack& stack, int& number)//出栈
{
	if (stackEmpty(stack))
		return false;
	else
	{
		--stack.top;//栈顶向下移
		int top = stack.top;
		number = stack.number[top];//元素出栈

	}

	return true;

}
int getPop(Stack& stack)//读取栈顶元素
{
	if (!stackEmpty(stack))
	{
		int i = stack.top - 1;
		return stack.number[i];
	}

}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浅隐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值