二叉树的实现

一、二叉树的创建与遍历

二叉树,子树最多有两个节点

 

前序遍历

根——>左——>右

我们先找到根也就是A

左就是左边的这些,这也是一个树也要根据根,左,右的顺序,B,D,遍历结束

右是右边的这三个,也是一个树,根据根,左,右的顺序,C ,F,G

 

 

 

#pragma warning(disable:4996)
#include<stdio.h>
#include<stdlib.h>
//下面是我们树的一个节点
typedef struct TreeNode {

	char data;
	struct TreeNode* Ichild;//左指针
	struct TreeNode* Rchild;//右指针

}TreeNode;
//创建树
//要想改变实参c语言中只能使用二次指针

/*这里要传入二重指针,因为我们的目的是在函数体内部改变(*T)的指向,只有传入二重才能改变一
重指针的指向,否则无效,就像想改变一个变量,我们需要取地址传入。*/


void createTree(TreeNode** T,char* data,int* index) //直接输入data一个序列去创建二叉树,index去遍历这个串,T是节点空间的指针
{
	char ch;
	ch = data[*index];
	*index += 1;//这是反引用,意思是索引下移
	scanf("%c\n", &ch);//接受我们传入的字符
	if (ch == '#') {
	//空节点
		*T = NULL;//代表该结点为空
	}
	//开辟一个节点存放数据,生成子树
	else {
	//非空节点
		*T = (TreeNode*)malloc(sizeof(TreeNode));//开辟空间
		(*T) ->data = ch;//将传入的data存放到开辟的空间中去
		//递归法
		createTree(&((*T)->Ichild),data,index);//左子树
		createTree(&((*T)->Rchild),data,index);//右子树
	}
}
//遍历
void preorder(TreeNode* T) {
	if (T == NULL) {
		return;
	}
	else {
		//先办事
	
		printf("%c", T->data);//打印
		//递归,处理孩子
		preorder(T->Ichild);
		preorder(T->Rchild);
	}


}

void inorder(TreeNode* T) {
	if (T == NULL) {
		return;
	}
	else {

		inorder(T->Ichild);//处理左孩子
	

		printf("%c", T->data);//办事
		

		inorder(T->Rchild);//处理右孩子
	}


}
void postorder(TreeNode* T) {
	if (T == NULL) {
		return;
	}
	else {

		postorder(T->Ichild);//处理左孩子


		postorder(T->Rchild);//处理右孩子


		printf("%c", T->data);//办事
	}


}

int main(int argc, char* argv[]) {
	int index = 0;

	TreeNode* T;
	createTree(&T,argv[1],&index);
	preorder(T);
	printf("\n");
	inorder(T);
	printf("\n");
	postorder(T);
	printf("\n");
	return 0;



}

二、二叉树的分层遍历

 

遍历顺序分层来就是 A B G   /C D H   /E  F

个人理解:

你出去了之后就要换你儿子进来一换多,寡王没儿子就不用进

 

#include<stdio.h>
#include<stdlib.h>
//二叉树
typedef struct TreeNode {

	char data;
	struct TreeNode* Ichild;
	struct TreeNode* Rchild;

}TreeNode;
//队列
typedef struct QueueNode {
	TreeNode* data;
	struct QueueNode* pre;
	struct QueueNode* next;
} QueueNode;

//创建树
void createTree(TreeNode** T, char* data,int*index) {
	char ch;
	ch = data[*index];
	*index += 1;
	if (ch = '#') {
		*T = NULL;
	}
	else {
	
		*T = (TreeNode*)malloc(sizeof(TreeNode));
		(*T)->data = ch;
		createTree(&((*T)->Ichild), data, index);//左子树
		createTree(&((*T)->Rchild), data, index);//右子树
	
	}

}
//创建队
QueueNode* initQueue() {

	QueueNode* Q = (QueueNode*)malloc(sizeof(QueueNode));//为队列创建头节点
	Q->data = NULL;//初始化
	Q->next = Q;//双链表指向自己,就是初始化
	Q->pre = Q;
	return Q;
}



void preOrder(TreeNode* T) {
	if (T == NULL) {
		return;
	}
	else {
		printf("%c ", T->data);
		preOrder(T->Ichild);
		preOrder(T->Rchild);
	}
}

//入队
void enQueue(TreeNode* data, QueueNode* Q) {
	QueueNode* node = (QueueNode*)malloc(sizeof(QueueNode));//创建新的节点空间
	node->data = data;//赋值
	//尾插法
	node->pre = Q;//node节点的pre指向头节点
	node->next = Q;
	Q->pre->next = node;//最后一个节点的next指针指向node,我们有一个空的头节点
	Q->pre = node;//Q的头部指向它
}
//判断队列是否满
int isEmpty(QueueNode* Q) {
	if (Q->next == Q) {
		return 1;
	}
	else {
		return 0;
	
	}

}
 //出队
QueueNode* deQueue(QueueNode* Q) {
	if (isEmpty(Q)) {
		return NULL;
	}
	else {
		QueueNode* node = Q->next;
		Q->next->next->pre = Q;
		Q->next = Q->next->next;
		return node;
	
	}
}
void levelTraverse(QueueNode* Q, TreeNode* T) {
	enQueue(T, Q);
	while (!isEmpty(Q)) {
		QueueNode* node = deQueue(Q);//接受出队的节点
		printf("%c ", node->data->data);
		if (node->data->Ichild) //左儿子存在
		{
			enQueue(node->data->Ichild, Q);
		}
		if (node->data->Rchild)//右儿子存在
		{
			enQueue(node->data->Rchild, Q);
		}
	}
}
                                                 
int main(int argc, char* argv[]) {
	TreeNode* T;
	int index = 0;
	QueueNode* Q = initQueue();
	createTree(&T, argv[1], &index);//argv[1]表示程序运行以后输入的第二个字符
	preOrder(T);
	printf("\n");
	levelTraverse(Q, T);
	printf("\n");
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值