当前位置:萝卜系统 > 硬件软件教程 > 详细页面

如何使用非递归算法完成二进制排序树的创建

如何使用非递归算法完成二进制排序树的创建

更新时间:2023-06-24 文章作者:未知 信息来源:网络 阅读次数:

根据运行的环境,操作系统可以分为桌面操作系统,手机操作系统,服务器操作系统,嵌入式操作系统等。

排序二叉树的遍历_建立二叉排序树_二叉树的排序

1. 如何使用非递归算法构建二进制排序树?

2. 我们都知道二进制排序树是二进制树建立二叉排序树,而二进制树实际上是带有双指针的链表,那么如何插入链表?我们来看一下在链表中插入值的算法:

#include <stdio.h>
#define null NULL
typedef struct Node{
	struct Node *next;//下一指针
	int data;//数据域 
}Node ;
//将数据插入到单链表中 
void insertData(Node *&L,int data){
	Node *r;//新建一个指针 
	Node *q ;
	r = L;//赋值 
	while(r->next!=null){
		if(r->next->data > data ){//找到第一个大于值的节点 			
			q = new Node;//指向一个新的结点
			q->data = data;
			r->next = q;
			q->next = r->next->next; 
		}
		else	r = r->next	;
	} 
	if(r->next == null){
		q = new Node;//指向一个新的结点
		q->data = data;
		r->next = q;
		q->next = null; 
	}	
}
//遍历单链表
void traverseLinkList(Node *L){	
	L = L->next;
	while(L!=null){
		printf("%d ",L->data);
		L = L->next;
	}
} 
int main(){
	Node *L;//单链表的表头
	L = new Node;//这一步,非常重要!指向一个具体结点!
	L->next = null; 
	int number;
	printf("请输入插入的数据个数!\n");	
	scanf("%d",&number);
	int data;
	for(int i = 0;i<number;i++){
		scanf("%d",&data);//输入数据
		insertData(L,data);//往单链表中插入数据 
	}
	//遍历输出 
	traverseLinkList(L);
} 
/*
4
1 2 3 4
*/
 

建立二叉排序树_二叉树的排序_排序二叉树的遍历

3. 让我们看一下此插入值的insertData函数

void insertData(Node *&L,int data){
	Node *r;//新建一个指针 
	Node *q ;
	r = L;//赋值 
	while(r->next!=null){
		if(r->next->data > data ){//找到第一个大于值的节点 			
			q = new Node;//指向一个新的结点
			q->data = data;
			r->next = q;
			q->next = r->next->next; 
		}
		else	r = r->next	;
	} 
	if(r->next == null){
		q = new Node;//指向一个新的结点
		q->data = data;
		r->next = q;
		q->next = null; 
	}	
}

(1)我们需要创建一个新的Node * r和Node * q; r是为了防止直接使用L导致L成为指向最后一个节点的指针(因此导致无法直接输出). 因此,您需要使用指针r临时存储L的值

二叉树的排序_建立二叉排序树_排序二叉树的遍历

(2)此处的指针q是什么?这是准备一个新的插入节点,因为我们需要将插入的值放入该节点,因此q指向此插入的节点.

(3)插入过程是什么?它基于判断while(r-> next!= null),因为我们需要判断当前节点,并在当前节点的前一个节点的末尾插入建立二叉排序树,这就是跟随指针!

但是这里我不使用以下指针,而是遵循指针的想法,每个人都必须拥有它!因为这在构建二叉树的过程中至关重要.

建立二叉排序树_二叉树的排序_排序二叉树的遍历

4. 现在回到主题,让我们看一下该二进制排序树的非递归方法的实现功能

void insertBiTree_2(BiTree *&bt,int da){	
	//先判断树是否为空-->如果为空,则建树,直接返回 
	if(bt==null){	
		bt = new BiTree;//因为在main函数中,bt是null,所以需要先让其指向一个节点,才能在该节点上赋值操作! 
		bt->data = da;
		bt->lChild = null;
		bt->rChild = null;
		return ;
	} 	
	BiTree *pre;//探索指针
	pre = bt;
	
	BiTree *follow;//跟随指针
	follow = bt;
			
	int flag = -1; 
	while(pre!=NULL){	
		if(pre->data <= da ) {//需要循环测试是否为null
			follow = pre;//暂存值 
			pre = pre->rChild; //变化的是follow!!
			flag = 1;
		}
		else if( pre != null && pre->data > da ){//需要循环测试是否为null 
			follow = pre;//暂存值 
			pre = pre->lChild;//变化的是follow!!
			flag = -1;
		}		
	}
	//注意!!如果说是跟随指针发现孩子为null,则添加节点,且将当前指针(pre)的孩子设成temp 
	if(pre == null){
		//下面是新建一个BiTree节点,并将其修改成标志的二叉树节点(左右子树均赋为空) 
		BiTree *temp;	
		temp = new BiTree; 
		temp->data = da;//插入数据
		temp->lChild = null;
		temp->rChild = null;
		
		if(flag == 1){
			follow->rChild = temp;	
			flag = -1; 
		}
		else if(flag == -1){
			follow->lChild = temp;
			flag = -1;
		}
	}	
} 

(1)Pre是探查指针,探查指针是什么,意味着判断当前值的大小和插入值的大小,而跟随指针则保留当前的pre,因为pre在进行大小比较之后,需要将其更改为指向左或右子树的指针. 但是,当我们插入值时,我们将按照以下步骤进行操作. [跟随者被命名为跟随指针]

二叉树的排序_建立二叉排序树_排序二叉树的遍历

(2)以下是典型的错误代码. 当然,此代码也是由作者本人编写的. . .

//插入数据-->建立一棵二叉树
//如果你硬要使用这种方式来创建一棵二叉树,那么你需要一个头结点 
void insertBiTree_2(BiTree *&temp,int da){	
	//BiTree *temp;
	//temp = bt;
		
	//先找到合适的位置--->如果说temp不为null 
	//这里是一个while(temp!=null)循环的原因:可能是在左子树,也可能是右子树 
	while(temp!=NULL){	
		if(temp->data < da ) {//需要循环测试是否为null
			temp = temp->rChild;
		}
		else if( temp != null && temp->data > da ){//需要循环测试是否为null 
			temp = temp->lChild;
		}		
	}
	if(temp == null){
		temp = new BiTree; 
		temp->data = da;//插入数据
		temp->lChild = null;
		temp->rChild = null;	
	}	
} 

这里有很多错误:

(1)直接修改温度是否正确?不需要进行临时的价值保护吗? --->您需要申请一个指向bt的指针,而不是直接使用它

(2)在while()循环中,如果添加了右子树的叶节点,则if(temp-> data> da)在这里将是错误的! [因为temp-> data不存在,即temp == null]

(3)当然,最关键的错误是我们没有使用以下指针,导致每次结果为temp == null时,就不可能建立完整的数字,从而导致失败输出.

6. 该程序的源代码如下所示


本文来自本站,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-250949-1.html



温馨提示:喜欢本站的话,请收藏一下本站!

本类教程下载

系统下载排行

网站地图xml | 网站地图html