树代码非递归(转)

本文介绍了一种非递归方式实现二叉树的先序遍历和层序遍历的方法。先序遍历使用了链式栈来辅助完成,而层序遍历则借助链式队列。每部分都详细展示了相关数据结构的操作流程,如栈和队列的创建、入栈/入队、出栈/出队及释放等。

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

先序遍历


void unpre_order(btree_pnode t)          //采用非递归方法先序遍历
{
	linklist top;//top为指向栈顶结点的指针
 
	top=stack_create();//初始化链式栈
	
	while(t!=NULL || !(stack_empty(top)))
	{
	
			if(t!=NULL)
			{
				printf("%c",t->data);
				if(t->rchild !=NULL)
					stack_push(top,t->rchild);  //入栈
				t=t->lchild;
			}
		else
			t=stack_pop(top);   //出栈
		}
 
	stack_free(top);   //释放栈
	
}


void unpre_order(btree_pnode t)          //采用非递归方法先序遍历
{
	linklist top;//top为指向栈顶结点的指针
 
	top=stack_create();//初始化链式栈
	/*
		该函数包含的头文件 和 实现方法如下:
		#include "linkstack.h"   //链式栈的头文件,关于链式栈的相关函数实现方法请查看博主相关链式栈的文章,这里不做细讲
		linklist stack_create()
		{
			linklist s;
 
			if((s=(linklist)malloc(sizeof(listnode)))==NULL){
				puts("malloc failed");
				return NULL;
			}
			s->next=NULL;
 
			return s;
		}
	*/
	while(t!=NULL || !(stack_empty(top))){
		/*
			该函数包含的头文件 和 实现方法如下:
			#include "linkstack.h"   //链式栈的头文件,关于链式栈的相关函数实现方法请查看博主相关链式栈的文章,这里不做细讲
			int stack_empty(linklist s)  //判断栈是否为空(1表示空,0表示非空)
			{
				return (s->next==NULL ? 1:0);
			}
		*/
		if(t!=NULL){
			printf("%c",t->data);
			if(t->rchild !=NULL)
				stack_push(top,t->rchild);  //入栈
			/*
				该函数包含的头文件 和 实现方法如下:
				#include "linkstack.h"   //链式栈的头文件,关于链式栈的相关函数实现方法请查看博主相关链式栈的文章,这里不做细讲
				int stack_push(linklist s,datatype_ls value)  //入栈
				{
					linklist p;
					if((p=(linklist)malloc(sizeof(listnode)))==NULL)
					{
						puts("malloc failed");
						return -1;
					}
 
					p->data = value;
					p->next=s->next;
					s->next = p;
 
					return 0;
				}
			*/
			t=t->lchild;
		}else
			t=stack_pop(top);   //出栈
		/*
			该函数包含的头文件 和 实现方法如下:
			#include "linkstack.h"   //链式栈的头文件,关于链式栈的相关函数实现方法请查看博主相关链式栈的文章,这里不做细讲
			datatype_ls stack_pop(linklist s)    //出栈
			{
				linklist p;
				datatype_ls ret;
 
				p=s->next;
				s->next=p->next;
				ret=p->data;
 
				free(p);
				p=NULL;
 
				return ret;
			}
		*/
	}
 
	stack_free(top);   //释放栈
	/*
		该函数包含的头文件 和 实现方法如下:
		#include "linkstack.h"   //链式栈的头文件,关于链式栈的相关函数实现方法请查看博主相关链式栈的文章,这里不做细讲
		void stack_free(linklist s)    //释放栈
		{
			linklist p;
 
			printf("free:");
			p=s;
			while(p)
			{
				s=s->next;
				printf("%d ",p->data);
				free(p);
				p=s;
			}
			putchar(10);    //10 表示 回车符('\n')
 
		}
	*/
}

--------------------- 
作者:许新天 
来源:优快云 
原文:https://blog.youkuaiyun.com/weixin_39148042/article/details/80960356 
版权声明:本文为博主原创文章,转载请附上博文链接!

层序遍历

void level_order(btree_pnode t)        //层次遍历
{
	link_pqueue q;
	init_linkqueue(&q);//初始化链式队列
	 
	while(t!=NULL)
	{
		//访问t指向的结点数据
		printf("%c",t->data);
		//当t的左指针不为空,则入队
		if(t->lchild!=NULL)
			in_linkqueue(t->lchild,q);
		
		//当t的右指针不为空,则入队
		if(t->rchild!=NULL)
			in_linkqueue(t->rchild,q);
		//队列不为空,则出队
		if(!is_empty_linkqueue(q))
			out_linkqueue(q,&t);
		
		else
			break;
	}
	free_linkqueue(q);           //释放队列

}

void level_order(btree_pnode t)        //层次遍历
{
	link_pqueue q;
	init_linkqueue(&q);//初始化链式队列
	/*
		该函数包含的头文件 和 实现方法如下:
		#include "linkqueue.h"   //链式队列的头文件,关于链式队列的相关函数实现方法请查看博主相关链式队列的文章,这里不做细讲
		void init_linkqueue(link_pqueue *Q)     //创建队列
		{
			//申请front和rear的空间
			*Q=(link_pqueue)malloc(sizeof(link_queue));
			if((*Q)==NULL)
			{
				perror("malloc");
				exit(-1);
			}
			//申请头结点空间
			(*Q)->front=(linkqueue_pnode)malloc(sizeof(linkqueue_node));
			if((*Q)->front==NULL)
			{
				perror("malloc");
				exit(-1) ;
			}
 
			(*Q)->front->next=NULL;
			(*Q)->rear=(*Q)->front;
 
			return;
		}
	*/
 
	while(t!=NULL)
	{
		//访问t指向的结点数据
		printf("%c",t->data);
		//当t的左指针不为空,则入队
		if(t->lchild!=NULL)
			in_linkqueue(t->lchild,q);
		/*
			该函数包含的头文件 和 实现方法如下:
			#include "linkqueue.h"   //链式队列的头文件,关于链式队列的相关函数实现方法请查看博主相关链式队列的文章,这里不做细讲
			bool in_linkqueue(datatype data,link_pqueue q)   //入队
			{
				linkqueue_pnode  new;
 
				//申请数据结点空间
				new=(linkqueue_pnode)malloc(sizeof(linkqueue_node));
				if(new==NULL)
				{
					puts("入队失败!");
					return false;
				}
				//将数据存储在申请的空间
				new->data=data;
	
				//将new指向的结点插入到链式队列中
				new->next=q->rear->next;            //这里等价于new->next = NULL;
				q->rear->next=new;         
	
				//让rear指针指向新的队尾结点
				q->rear=q->rear->next;          //等价于q->rear = new;
 
				return true;
			}
		*/
		//当t的右指针不为空,则入队
		if(t->rchild!=NULL)
			in_linkqueue(t->rchild,q);
		//队列不为空,则出队
		if(!is_empty_linkqueue(q))
			out_linkqueue(q,&t);
		/*
			该函数包含的头文件 和 实现方法如下:
			#include "linkqueue.h"   //链式队列的头文件,关于链式队列的相关函数实现方法请查看博主相关链式队列的文章,这里不做细讲
			bool out_linkqueue(link_pqueue q,datatype *D)      //出队
			{
				linkqueue_pnode t;
				//判断队列是否空
				if(is_empty_linkqueue(q)){
					printf("队列已空!\n");
					return false;
				}
 
				//出队
				t=q->front;
				q->front =q->front->next;
				*D=q->front->data;
				free(t);
 
				return true;
			}
		*/
		else
			break;
	}
	free_linkqueue(q);           //释放队列
	/*
		该函数包含的头文件 和 实现方法如下:
		#include "linkqueue.h"   //链式队列的头文件,关于链式队列的相关函数实现方法请查看博主相关链式队列的文章,这里不做细讲
		void free_linkqueue(link_pqueue q)           //释放队列
		{
			link_pqueue p;
			p = q->front;
			while(p)
			{
				q->front = q->front->next;
				free(p);
				p = q->front;
			}
			free(q);
		}
	*/
}

--------------------- 
作者:许新天 
来源:优快云 
原文:https://blog.youkuaiyun.com/weixin_39148042/article/details/80960356 
版权声明:本文为博主原创文章,转载请附上博文链接!
### 二叉排序插入操作的非递归C语言实现 以下是基于引用内容和专业知识所提供的二叉排序插入操作的非递归C语言实现代码: ```c #include <stdio.h> #include <stdlib.h> // 定义二叉排序节点结构体 typedef struct Node { int data; // 节点存储的数据 struct Node* left; // 左子指针 struct Node* right; // 右子指针 } Node; // 创建新节点 Node* createNode(int value) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = value; newNode->left = NULL; newNode->right = NULL; return newNode; } // 非递归方式插入节点到二叉排序中 void nonRecursiveInsert(Node** root, int value) { if (*root == NULL) { // 如果为空,直接创建根节点 *root = createNode(value); return; } Node* current = *root; // 当前遍历节点 Node* parent = NULL; // 记录当前节点的父节点 while (current != NULL) { // 查找合适的插入位置 parent = current; if (value < current->data) { current = current->left; // 移动到左子 } else { current = current->right; // 移动到右子 } } // 找到合适的位置后,插入新节点 if (value < parent->data) { parent->left = createNode(value); // 插入到左子 } else { parent->right = createNode(value); // 插入到右子 } } ``` #### 解析 上述代码实现了二叉排序非递归插入方法。其核心逻辑在于通过循环找到适合插入的新节点位置,并将其挂载到对应的父节点下[^1]。 具体流程如下: - 判断当前是否为空,若为空则直接创建根节点并赋值。 - 使用`while`循环逐步向下寻找插入位置,直到到达叶子节点为止。 - 根据数值大小关系决定移动方向(左子或右子),最终完成插入操作。 此方法的时间复杂度为O(h),其中h表示的高度[^3]。 --- ### 中序遍历验证二叉排序 为了验证插入后的二叉排序是否满足有序性,可以提供一个简单的中序遍历函数作为辅助工具: ```c void inorderTraversal(Node* root) { if (root == NULL) { return; } inorderTraversal(root->left); // 先访问左子 printf("%d ", root->data); // 输出当前节点数据 inorderTraversal(root->right); // 再访问右子 } ``` 调用该函数即可按升序打印整个二叉排序中的所有元素。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值