蛋疼,索搜二叉树不使用递归不用栈进行三种遍历

没事蛋疼搞了搞,不用递归,不用栈来实现二叉树的遍历,为了代码方便易用,哥搞成单步遍历模式

先搞个接口

//
// 中序遍历 & 逆中序遍历
const binary_search_tree_node_t* get_binary_search_tree_inorder_begin_node (const binary_search_tree_node_t* PARAM_IN proot_node);
const binary_search_tree_node_t* get_binary_search_tree_inorder_end_node (const binary_search_tree_node_t* PARAM_IN proot_node);

const binary_search_tree_node_t* binary_search_tree_inorder_increase (const binary_search_tree_node_t* PARAM_IN pcurrent_node,const binary_search_tree_node_t* PARAM_IN proot_node);

const binary_search_tree_node_t* binary_search_tree_inorder_decrease (const binary_search_tree_node_t* PARAM_IN pcurrent_node,const binary_search_tree_node_t* PARAM_IN proot_node);
//
// 后序遍历
const binary_search_tree_node_t* get_binary_search_tree_posorder_begin_node (const binary_search_tree_node_t* PARAM_IN proot_node);

const binary_search_tree_node_t* get_binary_search_tree_posorder_end_node (const binary_search_tree_node_t* PARAM_IN proot_node);

const binary_search_tree_node_t* binary_search_tree_posorder_increase (const binary_search_tree_node_t* PARAM_IN pcurrent_node,const binary_search_tree_node_t* PARAM_IN proot_node);

先序遍历,要实现这个蛋疼的想法,比较麻烦,要加多很点代码

//
// 先序遍历
typedef struct st_preorder_iterator
{
	const binary_search_tree_node_t*	m_pcurrent_node;
	//const binary_search_tree_node_t*	m_plast_sub_root;
	pfx_enum_t			        m_next_node_type;
	pfx_result_t			        m_last_result;
}pfx_preorder_iterator_t;

typedef enum enum_preorder_iterator_next_node_type
{
	PREORDER_NEXT_SUB_ROOT_RIGHT = 0,
	PREORDER_NEXT_SUB_ROOT_LEFT,
	PREORDER_NEXT_LEFT,
	PREORDER_NEXT_RIGHT,
	PREORDER_NEXT_BEGIN,
	PREORDER_NEXT_END,
	PREORDER_FIN,

	enum_preorder_iterator_next_node_type_COUNT
}pfx_preorder_iterator_next_node_type_t;

const binary_search_tree_node_t* get_binary_search_tree_preorder_begin_node (const binary_search_tree_node_t* PARAM_IN proot_node);

const binary_search_tree_node_t* get_binary_search_tree_preorder_end_node (const binary_search_tree_node_t* PARAM_IN proot_node);

const pfx_preorder_iterator_t* get_binary_search_tree_preorder_begin_iterator(const binary_search_tree_node_t* PARAM_IN proot_node,pfx_preorder_iterator_t* PARAM_INOUT piterator);

const pfx_preorder_iterator_t* get_binary_search_tree_preorder_end_iterator(const binary_search_tree_node_t* PARAM_IN proot_node,pfx_preorder_iterator_t* PARAM_INOUT piterator);

const pfx_preorder_iterator_t* binary_search_tree_preorder_increase (pfx_preorder_iterator_t* PARAM_INOUT piterator,const binary_search_tree_node_t* PARAM_IN proot_node);

 要实现这样蛋疼的想法,至于树的结构嘛,肯定是要三叉链表的,二叉链表的话,不递归要蛋疼的栈,写出来的代码,就不是人读了。

// 二叉树内部标记,主要用于平衡树应用
typedef struct st_binary_search_tree_node_mask
{
	unsigned		m_revered_mask	: 8;		// 保留位
	unsigned		m_valid_mask	: 8;		// 合法性判断位,用于假删除
	unsigned 	m_balance_mask	: 16;	// 平衡树标志位
}st_binary_search_tree_node_mask_t;

typedef union un_binary_search_tree_node_mask
{
	st_binary_search_tree_node_mask_t	m_mask;
	pfx_bitfield_t				m_mask_bits;
}binary_search_tree_node_mask_t;

// 二叉树节点基本结构
typedef struct st_binary_search_tree_node binary_search_tree_node_t;

struct st_binary_search_tree_node
{
	binary_search_tree_node_t*  m_parent_node;// 父节点,主要用于优化遍历以及可修改型迭代器的应用
	binary_search_tree_node_t*  m_pleft_node; // 左子树
	binary_search_tree_node_t*  m_pright_node;// 右子树
	binary_search_tree_node_mask_t	m_mask;	// 内部标记,平衡树扩展应用
	pfx_long_t m_key;			//	 键
};

 

 代码实现

 

//中序
const binary_search_tree_node_t* get_binary_search_tree_inorder_begin_node (const binary_search_tree_node_t* PARAM_IN proot_node)
{
	if (null != proot_node)
	{
		return min_binary_search_tree_node_unsafe(proot_node);
	}
	else
	{
		return null;
	}
}

const binary_search_tree_node_t* get_binary_search_tree_inorder_end_node (const binary_search_tree_node_t* PARAM_IN proot_node)
{
	if (null != proot_node)
	{
		return max_binary_search_tree_node_unsafe(proot_node);
	}
	else
	{
		return null;
	}
}

const binary_search_tree_node_t* binary_search_tree_inorder_increase (const binary_search_tree_node_t* PARAM_IN pcurrent_node,const binary_search_tree_node_t* PARAM_IN proot_node)
{
	if (null == pcurrent_node || null == proot_node)
	{
		return null;
	}

	if (pcurrent_node == proot_node)
	{
		if (null != pcurrent_node->m_pright_node)
		{
			return min_binary_search_tree_node_unsafe(pcurrent_node->m_pright_node);
		}
		else
		{
			return null;
		}
	}

	if (null != pcurrent_node->m_pright_node)
	{
		return min_binary_search_tree_node_unsafe(pcurrent_node->m_pright_node);
	}


	if (pcurrent_node->m_parent_node->m_pleft_node == pcurrent_node)
	{
		return pcurrent_node->m_parent_node;
	}

	if (pcurrent_node == pcurrent_node->m_parent_node)
	{
		return null;
	}

	pcurrent_node =  pcurrent_node->m_parent_node;
	while (null != pcurrent_node->m_parent_node)
	{
		if (pcurrent_node->m_parent_node->m_pright_node == pcurrent_node)
		{
			pcurrent_node = pcurrent_node->m_parent_node;
			continue;
		}
		if (pcurrent_node->m_parent_node->m_pleft_node == pcurrent_node)
		{
			pcurrent_node = pcurrent_node->m_parent_node;
			break;
		}

	}
	return pcurrent_node;
}
const binary_search_tree_node_t* binary_search_tree_inorder_decrease (const binary_search_tree_node_t* PARAM_IN pcurrent_node,const binary_search_tree_node_t* PARAM_IN proot_node)
{
	if (null == pcurrent_node || null == proot_node)
	{
		return null;
	}

	if (pcurrent_node == proot_node)
	{
		if (null != pcurrent_node->m_pleft_node)
		{
			return max_binary_search_tree_node_unsafe(pcurrent_node->m_pleft_node);
		}
		else
		{
			return null;
		}
	}

	if (null != pcurrent_node->m_pleft_node)
	{
		return max_binary_search_tree_node_unsafe(pcurrent_node->m_pleft_node);
	}

	if (pcurrent_node->m_parent_node->m_pright_node == pcurrent_node)
	{
		return pcurrent_node->m_parent_node;
	}

	if (pcurrent_node == pcurrent_node->m_parent_node)
	{
		return null;
	}

	pcurrent_node =  pcurrent_node->m_parent_node;
	while (null != pcurrent_node->m_parent_node)
	{
		if (pcurrent_node->m_parent_node->m_pleft_node == pcurrent_node)
		{
			pcurrent_node = pcurrent_node->m_parent_node;
			continue;
		}
		if (pcurrent_node->m_parent_node->m_pright_node == pcurrent_node)
		{
			pcurrent_node = pcurrent_node->m_parent_node;
			break;
		}

	}
	return pcurrent_node;
		
}


// 后序
const binary_search_tree_node_t* get_binary_search_tree_posorder_begin_node (const binary_search_tree_node_t* PARAM_IN proot_node)
{
	if (null != proot_node)
	{
		const binary_search_tree_node_t* ptemp_node = null;
		
		while (null != proot_node)
		{
			ptemp_node = proot_node;
			if (null != proot_node->m_pleft_node)
			{
				proot_node = proot_node->m_pleft_node;
				continue;
			}
			else 	if (null != proot_node->m_pright_node)
			{
				proot_node = proot_node->m_pright_node;
				continue;
			}
			else
			{
				break;
			}

		}
		return ptemp_node;
		
	}
	else
	{
		return null;
	}
}

const binary_search_tree_node_t* get_binary_search_tree_posorder_end_node (const binary_search_tree_node_t* PARAM_IN proot_node)
{
	return proot_node;
}

const binary_search_tree_node_t* binary_search_tree_posorder_increase (const binary_search_tree_node_t* PARAM_IN pcurrent_node,
	const binary_search_tree_node_t* PARAM_IN proot_node)
{
	if (pcurrent_node == proot_node)
	{
		return null;
	}

	if (null == pcurrent_node->m_parent_node)
	{
		return null;
	}

	if (pcurrent_node->m_parent_node->m_pright_node == pcurrent_node)
	{
		return pcurrent_node->m_parent_node;
	}

	if (pcurrent_node->m_parent_node->m_pleft_node == pcurrent_node)
	{
		const binary_search_tree_node_t* ptemp_node;
		const binary_search_tree_node_t* ptemp_node_retn;
		ptemp_node = pcurrent_node->m_parent_node->m_pright_node;
		ptemp_node_retn = pcurrent_node->m_parent_node;

		while (null != ptemp_node)
		{
			ptemp_node_retn = ptemp_node;
			if (null != ptemp_node->m_pleft_node)
			{
				ptemp_node = ptemp_node->m_pleft_node;
				continue;
			}
			else if (null != ptemp_node->m_pright_node)
			{
				ptemp_node = ptemp_node->m_pright_node;
				continue;
			}
			else
			{
				break;
			}

		}
		
		return ptemp_node_retn;
	}

	return null;
}
//先序
const binary_search_tree_node_t* get_binary_search_tree_preorder_begin_node (const binary_search_tree_node_t* PARAM_IN proot_node)
{
	return proot_node;
}

const binary_search_tree_node_t* get_binary_search_tree_preorder_end_node (const binary_search_tree_node_t* PARAM_IN proot_node)
{
	if (null != proot_node)
	{
		const binary_search_tree_node_t* ptemp_node = null;

		while (null != proot_node)
		{
			ptemp_node = proot_node;
			if (null != proot_node->m_pright_node)
			{
				proot_node = proot_node->m_pright_node;
				continue;
			}
			else if (null != proot_node->m_pleft_node)
			{
				proot_node = proot_node->m_pleft_node;
				continue;
			}
			else
			{
				break;
			}

		}
		return ptemp_node;

	}
	else
	{
		return null;
	}

}

const pfx_preorder_iterator_t* get_binary_search_tree_preorder_begin_iterator (const binary_search_tree_node_t* PARAM_IN proot_node,pfx_preorder_iterator_t* PARAM_INOUT piterator)
{
	RETURN_INVALID_RESULT((null == piterator),null);
	piterator->m_pcurrent_node = get_binary_search_tree_preorder_begin_node (proot_node);
	piterator->m_last_result = PFX_STATUS_OK;
	if (null != piterator->m_pcurrent_node)
	{
		if (null != piterator->m_pcurrent_node->m_pleft_node)
		{
			piterator->m_next_node_type = PREORDER_NEXT_LEFT;
		}
		else if (null != piterator->m_pcurrent_node->m_pright_node)
		{
			piterator->m_next_node_type = PREORDER_NEXT_RIGHT;
		}
		else
		{
			piterator->m_next_node_type = PREORDER_FIN;
		}
	}
	return piterator;
}

const pfx_preorder_iterator_t* get_binary_search_tree_preorder_end_iterator(const binary_search_tree_node_t* PARAM_IN proot_node,pfx_preorder_iterator_t* PARAM_INOUT piterator)
{
	RETURN_INVALID_RESULT ((null == piterator),null);
	piterator->m_pcurrent_node = get_binary_search_tree_preorder_end_node (proot_node);
	piterator->m_next_node_type = PREORDER_NEXT_END;

	return piterator;
}

const pfx_preorder_iterator_t* binary_search_tree_preorder_increase (pfx_preorder_iterator_t* PARAM_INOUT piterator,const binary_search_tree_node_t* PARAM_IN proot_node)
{
	pfx_enum_t back_up_next_type;
	pfx_enum_t next_type;
	const binary_search_tree_node_t* pnext_node;
	pfx_result_t	status = PFX_STATUS_OK;

	RETURN_INVALID_RESULT ((null == piterator || null == proot_node || 
		null == piterator->m_pcurrent_node || enum_preorder_iterator_next_node_type_COUNT <= piterator->m_next_node_type||
		PFX_STATUS_OK != piterator->m_last_result), null);

	back_up_next_type = piterator->m_next_node_type;

	switch (back_up_next_type)
	{
	case PREORDER_NEXT_SUB_ROOT_RIGHT:
		{
			const binary_search_tree_node_t* pcur_node =  piterator->m_pcurrent_node;
			do 
			{
				pnext_node = pcur_node->m_parent_node;
				if (pcur_node == proot_node)
				{
					status = PFX_STATUS_OK;
					next_type = PREORDER_FIN;
					break;
				}
				else if (null == pnext_node)
				{
					status = PFX_STATUS_OK;
					next_type = PREORDER_FIN;
					break;
				}
				else if (pnext_node->m_pright_node == pcur_node)
				{
					pcur_node = pnext_node;
					continue;
				}
				else if (pnext_node->m_pleft_node == pcur_node)
				{
					if (null == pnext_node->m_pright_node)
					{
						pcur_node = pnext_node;
						continue;
					}
					pnext_node = pnext_node->m_pright_node;
					status = PFX_STATUS_OK;

					if (null != pnext_node->m_pleft_node)
					{
						next_type = PREORDER_NEXT_LEFT;
						break;
					}
					else if (null != pnext_node->m_pright_node)
					{
						next_type = PREORDER_NEXT_RIGHT;
						break;
					}
					else
					{
						next_type = PREORDER_NEXT_SUB_ROOT_RIGHT;
						break;
					}

				}
				else
				{
					status = PFX_STATUS_MEM_ERR;
					next_type = PREORDER_FIN;
					pnext_node = null;
				}
			} while (1);
			piterator->m_pcurrent_node = pnext_node;
			piterator->m_next_node_type = next_type;
			piterator->m_last_result = status;
		}
		break;
	case PREORDER_NEXT_LEFT:
		{
			pnext_node = piterator->m_pcurrent_node->m_pleft_node;
			if (null == pnext_node)
			{
				status = PFX_STATUS_MEM_ERR;
				next_type = PREORDER_FIN;
			}
			else if (null != pnext_node->m_pleft_node)
			{
				next_type = PREORDER_NEXT_LEFT;
			}
			else if (null != pnext_node->m_pright_node)
			{
				next_type = PREORDER_NEXT_RIGHT;
			}
			else
			{
				next_type = PREORDER_NEXT_SUB_ROOT_RIGHT;
			}
			piterator->m_pcurrent_node = pnext_node;
			piterator->m_next_node_type = next_type;
			piterator->m_last_result = status;
		}
		break;
	case PREORDER_NEXT_RIGHT:
		{
			pnext_node = piterator->m_pcurrent_node->m_pright_node;
			if (null == pnext_node)
			{
				status = PFX_STATUS_MEM_ERR;
				next_type = PREORDER_FIN;
			}
			else if (null != pnext_node->m_pleft_node)
			{
				next_type = PREORDER_NEXT_LEFT;
			}
			else if (null != pnext_node->m_pright_node)
			{
				next_type = PREORDER_NEXT_RIGHT;
			}
			else
			{
				next_type = PREORDER_NEXT_SUB_ROOT_RIGHT;
			}
			piterator->m_pcurrent_node = pnext_node;
			piterator->m_next_node_type = next_type;
			piterator->m_last_result = PFX_STATUS_OK;
		}
		break;
	case PREORDER_NEXT_BEGIN:
		{
			 get_binary_search_tree_preorder_begin_iterator(proot_node,piterator);
		}
		break;
	case PREORDER_NEXT_END:
		{
			piterator->m_pcurrent_node = null;
			piterator->m_next_node_type = PREORDER_FIN;
			piterator->m_last_result = PFX_STATUS_OK;
		}
		break;
	default:
		{
			piterator->m_pcurrent_node = null;
			piterator->m_next_node_type = PREORDER_FIN;
			piterator->m_last_result = PFX_STATUS_INVALID_OPERATION;
		}
		break;
	}

	return piterator;
}

测试只做了简单的测试应该没大问题,缺测试数据,有一样蛋疼的可以给哥发点测试数据,或者你想测试的话,可以到github自己下代码https://github.com/burningsun/pecker_framework.git测试数据可以参照 \pecker_src\pecker_framework\test_data里面的格式写入,测试代码在pecker_src\pecker_framework\test\pfx_bst_test.cpp和pecker_src\pecker_framework\test\pfx_avl_test.cpp都有。


转载于:https://my.oschina.net/u/253717/blog/165690

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值