二叉树(按层遍历——队列模拟)

本文详细介绍了二叉树与队列的数据结构实现,包括二叉树的初始化、遍历方法以及队列的初始化、入队、出队操作。通过层序输入构建二叉树,并展示了前序、中序、后序和层次遍历的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

"队列.h"文件

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

typedef struct biTree elemType ;

struct node{
	elemType * elem;
	struct node * next;
};

struct queue{
	struct node * front;
	struct node * rear;
};

struct queue * initQueue();

struct queue * enQueue(struct queue * q,elemType elem);

struct queue * deQueue(struct queue * q);



struct queue * initQueue(){
	struct queue * q;
	q=(struct queue *)malloc(sizeof(struct queue));
	q->front=(struct node *)malloc(sizeof(struct node));
	q->rear=q->front;
	q->front->next=NULL;
	return q;
}

struct queue * enQueue(struct queue * q,elemType * elem){
	struct node * p;
	p=(struct node *)malloc(sizeof(struct node));
	p->elem=elem;
	p->next=NULL;
	q->rear->next=p;
	q->rear=p;
	return q;
}

struct queue * deQueue(struct queue * q){
	struct node * p;
	if(q->front==q->rear){
		printf("队列为空!无法删除!\n");
	}
	else{
		p=q->front->next;
		q->front->next=p->next;
		if(q->rear==p){
			q->rear=q->front;
		}
		free(p);
	}
	return q;
}


"二叉树.h"文件

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

struct biTree{
	char data;
	struct biTree * lchild, * rchild;
};

struct biTree * initBiTree();

struct biTree * createBiTree(struct biTree * bt);

int preOrderTraverse(struct biTree * bt);

int inOrderTraverse(struct biTree * bt);

int postOrderTraverse(struct biTree * bt);

int levelOrderTraverse(struct biTree * bt);

int test();



.c文件

#include "二叉树.h"
#include "队列.h"

#define MAX 100

struct biTree * createBiTree(struct biTree * bt){
	int front,rear;
	char ch;
	struct biTree * p,* Queue[MAX];
	front=1,rear=0;
	printf("按层输入二叉树,虚结点输入'#'(结束符为'@'):\n");
	while((ch=getchar())!='@'){
		p=NULL;
		if(ch!='#'){
			p=(struct biTree *)malloc(sizeof(struct biTree));
			p->data=ch;
			p->lchild=p->rchild=NULL;
		}
		rear++;
		Queue[rear]=p;
		if(rear==1){
			bt=p;
		}
		else{
			if(p!=NULL&&Queue[front]!=NULL){
				if(rear%2==0){
					Queue[front]->lchild=p;
				}
				else{
					Queue[front]->rchild=p;
				}
			}
			if(rear%2==1){
				front++;
			}
		}
	}
	return bt;
}

int preOrderTraverse(struct biTree * bt){
	if(bt!=NULL){
		printf("%c ",bt->data);
		preOrderTraverse(bt->lchild);
		preOrderTraverse(bt->rchild);
	}
	return 0;
}

int inOrderTraverse(struct biTree * bt){
	if(bt!=NULL){
		inOrderTraverse(bt->lchild);
		printf("%c ",bt->data);
		inOrderTraverse(bt->rchild);
	}
	return 0;
}

int postOrderTraverse(struct biTree * bt){
	if(bt!=NULL){
		postOrderTraverse(bt->lchild);
		postOrderTraverse(bt->rchild);
		printf("%c ",bt->data);
	}
	return 0;
}

int levelOrderTraverse(struct biTree * bt){
	struct queue * queue;
	struct biTree * p;
	queue=initQueue();
	if(bt!=NULL){
		p=bt;
		enQueue(queue,p);
		printf("%c ",p->data);
		while(queue->front!=queue->rear){
			p=queue->front->next->elem;
			if(p->lchild!=NULL){
				enQueue(queue,p->lchild);
				printf("%c ",p->lchild->data);
			}
			if(p->rchild!=NULL){
				enQueue(queue,p->rchild);
				printf("%c ",p->rchild->data);
			}
			deQueue(queue);
		}
	}
	return 0;
}

int test(){
	struct biTree * bt;
	bt=(struct biTree *)malloc(sizeof(struct biTree));
	bt=createBiTree(bt);
	preOrderTraverse(bt);
	printf("\n");
	inOrderTraverse(bt);
	printf("\n");
	postOrderTraverse(bt);
	printf("\n");
	levelOrderTraverse(bt);
	printf("\n");
	return 0;
}

int main(){
	test();
	return 0;
}

### 二叉树中序遍历的特性 #### 遍历顺序 对于任意给定的一棵二叉树,当中序遍历时遵循特定访问次序:先处理左子树,再访问根节点本身,最后才转向右子树[^1]。这种模式能够确保按照从小到大排列键值(假设为查找树),从而使得输出序列呈现升序状态。 #### 使用场景 当面对需要有序输出或者构建平衡搜索树的任务时,采用中序方式尤为合适。这是因为通过这种方式可以获得自然排序的数据流,在某些应用场景下可以直接利用而无需额外排序操作[^4]。 #### 实现方法 为了实现非递归形式下的中序遍历,通常借助于显式的栈来模拟函数调用堆栈的工作机制。每当遇到一个新的结点时就将其压入栈底;一旦到达叶子位置,则弹出最近一次保存的状态并记录当前元素值,随后尝试向右侧移动继续上述过程直到整个结构被完全解析完毕[^2]。 ```c++ // C++版本的中序非递归遍历伪代码示例 void InOrderNonRecursive(Node* root){ stack<Node*> s; Node *current = root; while (!s.empty() || current != nullptr) { // Reach the left most Node of the current Node if (current != nullptr) { s.push(current); current = current->left; } else{ // Current must be NULL at this point, pop from Stack and visit it. current = s.top(); s.pop(); cout << current->data << " "; // We have visited the node and its left subtree. Now, it's right subtree's turn current = current->right; } } } ``` #### 时间复杂度分析 无论是哪种具体实施方案——不论是基于迭代还是递归来完成相同功能——其时间效率均为O(n),其中n代表待处理节点总数目。这是因为在最坏情况下每个顶点都会恰好进出队列/栈两次[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值