二叉树遍历

这篇博客详细介绍了二叉树的各种遍历方法,包括递归和非递归的前序、中序、后序遍历,以及层次遍历。同时,还提供了创建二叉树、计算节点数量、判断是否为满二叉树或完全二叉树的函数,并展示了Z字型打印二叉树的方法。此外,还涵盖了寻找父节点和特定值节点的算法。
摘要由CSDN通过智能技术生成

二叉树数据结构

typedef char Elemtype;
typedef struct BtNode
{
	Elemtype data;
	struct BtNode* leftchild;
	struct BtNode* rightchile;
}BtNode,*BinaryTree;

二叉树遍历 递归

//前序遍历
void PreOrder(BtNode* p)
{
	if (p != NULL)
	{
		cout << p->data << " ";
		PreOrder(p->leftchild);
		PreOrder(p->rightchild);
	}
}
//中序遍历
void InOrder(BtNode* p)//ABC##DE##F##G#H##
{
	if (p != NULL)
	{
		InOrder(p->leftchild);
		cout << p->data<<" ";
		InOrder(p->rightchile);
	}
}
//后序遍历
void PastOrder(BtNode* p)
{
	if (p != NULL)
	{
		PastOrder(p->leftchild);
		PastOrder(p->rightchild);
		cout << p->data << " ";
	}
}

非递归法一

//非递归先序遍历
void NicePreOrder(BtNode* ptr)
{
	if (ptr == NULL) return;
	stack<BtNode*> st;
	st.push(ptr);
	while (!st.empty())
	{
		ptr = st.top(); st.pop();
		cout << ptr->data;
		if (ptr->rightchild != NULL)
		{
			st.push(ptr->rightchild);
		}
		if (ptr->leftchild != NULL)
		{
			st.push(ptr->leftchild);
		}
	}
	cout << endl;
}
//非递归中序遍历

void NiceInOrder(BtNode* ptr)
{
	if (ptr == NULL)return;
	std::stack<BtNode*>st;
	while (ptr != NULL || !st.empty())
	{
		while (ptr != NULL)
		{
			st.push(ptr);
			ptr = ptr->leftchild;
		}
		ptr = st.top(); st.pop();
		cout << ptr->data;
		ptr = ptr->rightchile;
	}
	cout << endl;
}
//非递归后序遍历
void NicePastOrder(BtNode* ptr)
{
	if (ptr == NULL)return;
	std::stack<BtNode*>st;
	BtNode* tag = nullptr;
	while (ptr != NULL || !st.empty())
	{
		while (ptr != NULL)
		{
			st.push(ptr);
			ptr = ptr->leftchild;
		}
		ptr = st.top(); st.pop();
		if (ptr->rightchile == nullptr || ptr->rightchile == tag)
		{
			cout << ptr->data;
			tag = ptr;
			ptr = nullptr;
		}
		else
		{
			st.push(ptr);
			ptr = ptr->rightchile;
		}
	}
	cout << endl;

}

非递归法二

struct StkNode
{
	BtNode* pnode;
	int pos; 
public:
	StkNode(BtNode* p) :pnode(p), pos(0) {}
};
//后序遍历
void StkNicePastOrder(BtNode* ptr)
{
	if (ptr == NULL) return;
	stack<StkNode> st;
	st.push(StkNode(ptr));
	while (!st.empty())
	{
		StkNode  node = st.top(); st.pop();
		if (++node.pos == 3)
		{
			cout << node.pnode->data;
		}
		else
		{
			st.push(node);
			if (node.pos == 1 && node.pnode->leftchild != NULL)
			{
				st.push(StkNode(node.pnode->leftchild));
			}
			else if (node.pos == 2 && node.pnode->rightchild != NULL)
			{
				st.push(StkNode(node.pnode->rightchild));
			}
		}
	}
	cout << endl;
}
//中序遍历
void StkNiceInOrder(BtNode* ptr)
{
	if (ptr == NULL) return;
	stack<StkNode> st;
	st.push(StkNode(ptr));
	while (!st.empty())
	{
		StkNode  node = st.top(); st.pop();
		if (++node.pos == 2)
		{
			cout << node.pnode->data;
			if (node.pnode->rightchild != NULL)
			{
				st.push(StkNode(node.pnode->rightchild));
			}
		}
		else
		{
			st.push(node);
			if (node.pnode->leftchild != NULL)
			{
				st.push(StkNode(node.pnode->leftchild));
			}
		}
	}
	cout << endl;
}

由中序遍历和后序遍历得到二叉树

BtNode* BuyNode()
{
	BtNode* s = (BtNode*)malloc(sizeof(BtNode));
	if (NULL == s)exit(1);
	memset(s, 0, sizeof(BtNode));
	return s;
}
int FindIs(const char* is, int n, char s)
{
	for (int i = 0; i < n; ++i)
	{
		if (is[i] == s)
		{
			return i;
		}
	}
	return -1;
}
BtNode* CreateIL(const char* is, const char* ls, int n)
{
	BtNode* s = NULL;
	if (n > 0)
	{
		s = BuyNode();
		s->data = ls[n - 1];
		int pos = FindIs(is, n, ls[n - 1]);
		if (pos == -1)exit(1);
		s->leftchild = CreateIL(is,ls,pos);
		s->rightchile = CreateIL(is+pos+1,ls+pos,n-pos-1);
	}
	return s;
}
BtNode* CreateBinaryTreeIL(const char* is, const char* ls, int n)
{
	if (is == NULL || ls == NULL || n <= 0)return NULL;
	else return CreateIL(is, ls, n);
}

二叉树层次遍历

void LevelOrder(BtNode* ptr)
{
	if (ptr == NULL) return;
	queue<BtNode*> qu;
	qu.push(ptr);
	while (!qu.empty())
	{
		ptr = qu.front(); qu.pop();
		cout << ptr->data;
		if (ptr->leftchild != NULL)
		{
			qu.push(ptr->leftchild);
		}
		if (ptr->rightchild != NULL)
		{
			qu.push(ptr->rightchild);
		}
	}
	cout << endl;
}

二叉树结点个数

int Count(BtNode* ptr)
{
	if (ptr == NULL) return 0;
	else return Count(ptr->leftchild) + Count(ptr->rightchild) + 1;
}

二叉树深度

int Depth(BtNode* ptr)
{
	if (ptr == NULL) return 0;
	else return std::max(Depth(ptr->leftchild), Depth(ptr->rightchild)) + 1;
}

Z字型打印二叉树

void ZLevelOrder(BtNode* ptr)
{
	if (ptr == NULL) return;
	stack<BtNode*> ast;
	stack<BtNode*> bst;
	ast.push(ptr);
	while (!ast.empty() || !bst.empty())
	{
		while(!ast.empty())
		{
			ptr = ast.top(); ast.pop();
			cout << ptr->data;
			if (ptr->leftchild != NULL)
			{
				bst.push(ptr->leftchild);
			}
			if (ptr->rightchild != NULL)
			{
				bst.push(ptr->rightchild);
			}
		}
		while(!bst.empty())
		{ 
			ptr = bst.top(); bst.pop();
			cout << ptr->data;
			if (ptr->rightchild != NULL)
			{
				ast.push(ptr->rightchild);
			}
			if (ptr->leftchild != NULL)
			{
				ast.push(ptr->leftchild);
			}
		}
	}
}

判断是否是满二叉树

bool Is_FullBinaryTree(BtNode* ptr)
{
	bool tag = true;
	if (ptr == NULL) return tag;
	queue<BtNode*> aqu;
	queue<BtNode*> bqu;
	int s = 1;
	aqu.push(ptr);
	while (!aqu.empty() || !bqu.empty())
	{
		if (s != aqu.size())
		{
			tag = false;
			break;
		}
		while (!aqu.empty())
		{
			ptr = aqu.front(); aqu.pop();
			if (ptr->leftchild != NULL) bqu.push(ptr->leftchild);
			if (ptr->rightchild != NULL) bqu.push(ptr->rightchild);
		}
		s += s;
		if (s != bqu.size())
		{
			tag = false;
			break;
		}
		while (!bqu.empty())
		{
			ptr = bqu.front(); bqu.pop();
			if (ptr->leftchild != NULL) aqu.push(ptr->leftchild);
			if (ptr->rightchild != NULL) aqu.push(ptr->rightchild);
		}
		s += s;
	}
	return tag;
}

判断二叉树是否是完全二叉树

bool Is_CompBinaryTree(BtNode* ptr)
{
	bool tag = true;
	if (ptr == NULL) return tag;
	queue<BtNode*> qu;
	qu.push(ptr);
	while (!qu.empty())
	{
		ptr = qu.front(); qu.pop();
		if (NULL == ptr) break;
		qu.push(ptr->leftchild);
		qu.push(ptr->rightchild);
	}
	while (!qu.empty())
	{
		if (qu.front() != NULL)
		{
			tag = false;
			break;
		}
		qu.pop();
	}
}

遍历数组二叉树

void InOrder(int* tree, int i, int n)
{
	if (i < n && tree[i] != -1)
	{
		InOrder(tree, i * 2 + 1, n); // leftchild;
		cout << tree[i] << " ";
		InOrder(tree, i * 2 + 2, n); // rightchild
	}
}

寻找val值得父节点

BtNode* FindPa(BtNode* ptr, BtNode* child)
{
	if (ptr == NULL || ptr->leftchild == child || ptr->rightchild == child)
	{
		return ptr;
	}
	else
	{
		BtNode* p = FindPa(ptr->leftchild, child);
		if (NULL == p)
		{
			p = FindPa(ptr->rightchild, child);
		}
		return p;
	}
}
BtNode* FindParent(BtNode* ptr, BtNode* child)
{
	if (ptr == NULL || child == NULL || ptr == child) return NULL;
	else return FindPa(ptr, child);
}

寻找val值的结点

BtNode* FindValue(BtNode* ptr, ElemType val)
{
	if (ptr == NULL || ptr->data == val)
	{
		return ptr;
	}
	else
	{
		BtNode* p = FindValue(ptr->leftchild, val);
		if (NULL == p)
		{
			p = FindValue(ptr->rightchild, val);
		}
		return p;
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值