树和二叉树

树和二叉树

1.二叉树的表示
2.二叉树的遍历
3.二叉树的基本操作

1.二叉树的表示

  • 结构设计
#define END '#'
typedef char ElemType;
typedef struct BtNode
{
	struct BtNode* leftchild;
	struct BtNode* rightchild;
	ElemType data;
}BtNode,*BinaryTree;

2.二叉树的遍历

所谓树的遍历,就是按某种次序访问树中的结点,要求每个结点访问一次且仅访问一次。

递归遍历

void PreOrder(BtNode* p)//先序遍历
{
	if (p != NULL)
	{
		printf("%c ", p->data);
		PreOrder(p->leftchild);
		PreOrder(p->rightchild);
	}
}

void InOrder(BtNode* p)//中序遍历
{
	if (p != NULL)
	{
		InOrder(p->leftchild);
		printf("%c ", p->data);
		InOrder(p->rightchild);
	}
}

void PastOrder(BtNode* p)//后序遍历
{
	if (p != NULL)
	{
		PastOrder(p->leftchild);
		PastOrder(p->rightchild);
		printf("%c ", 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;
	}
	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->rightchild;
	}
	cout << endl;
}

//非递归的后序遍历
//法一:
void NicePastOrder(BtNode* ptr)
{
	if (ptr == NULL)
	{
		return;
	}
	stack<BtNode*> st;
	BtNode* tag = NULL;
	while (ptr != NULL || !st.empty())
	{
		while (ptr != NULL)
		{
			st.push(ptr);
			ptr = ptr->leftchild;
		}
		ptr = st.top();
		st.pop();
		if (ptr->rightchild == NULL || ptr->rightchild == tag)
		{
			cout << ptr->data << " ";
			tag = ptr;
			ptr = NULL;
		}
		else
		{
			st.push(ptr);
			ptr = ptr->rightchild;
		}
	}
	cout << endl;
}
//法二:
struct StkNode
{
	int popnum;
	BtNode* pnode;
public:
	StkNode(BtNode* p = NULL) : popnum(0),pnode(p){}
};
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.popnum == 3)
		{
			cout << node.pnode->data << " ";
		}
		else
		{
			st.push(node);
			if (node.popnum == 1 && node.pnode->leftchild != NULL)
			{
				st.push(StkNode(node.pnode->leftchild));
			}
			else if (node.popnum == 2 && node.pnode->rightchild != NULL)
			{
				st.push(StkNode(node.pnode->rightchild));
			}
		}
	}
	cout << endl;
}

创建二叉树

struct BtNode* Buynode()//创建一个结点
{
	BtNode* s = (BtNode*)malloc(sizeof(*s));
	if (NULL == s)
		exit(EXIT_FAILURE);
	memset(s, 0, sizeof(*s));
	return s;
}
BtNode* CreateTree()
{
	ElemType ch;
	BtNode* s = NULL;
	cin >> ch;
	if (ch != END)
	{
		s = Buynode();
		s->data = ch;
		s->leftchild = CreateTree();
		s->rightchild = CreateTree();
	}
	return s;
}

利用先序和中序创建二叉树

int FindIs(char* is, int n, char val)
{
	int pos = -1;
	for (int i = 0; i < n; i++)
	{
		if (is[i] == val)
		{
			pos = i;
			break;
		}
	}
	return pos;
}
BtNode* CreatePI(char* ps, char* is, int n)
{
	BtNode* s = NULL;
	if (n > 0)
	{
		s = Buynode();
		s->data = ps[0];
		int pos = FindIs(is, n, ps[0]);
		if (pos == -1)
		{
			exit(EXIT_FAILURE);
		}
		s->leftchild = CreatePI(ps + 1, is, pos);
		s->rightchild = CreatePI(ps + 1 + pos, is + 1 + pos, n - pos - 1);
	}
	return s;
}
BtNode* CreateTreePI(char* ps, char* is, int n)//利用先序和中序创建二叉树
{
	BtNode* s = NULL;
	if (ps != NULL && is != NULL && n > 0)
	{
		s = CreatePI(ps, is, n);
	}
	return s;
}

利用中序和后序创建二叉树

int FindIs(char* is, int n, char val)
{
	int pos = -1;
	for (int i = 0; i < n; i++)
	{
		if (is[i] == val)
		{
			pos = i;
			break;
		}
	}
	return pos;
}
BtNode* CreateIL(char* is, 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(EXIT_FAILURE);
		s->leftchild = CreateIL(is, ls, pos);
		s->rightchild = CreateIL(is + pos + 1, ls + pos, n - pos - 1);
	}
	return s;
}
BtNode* CreateTreeIL(char* is, char* ls, int n)//利用中序和后序创建二叉树
{
	BtNode* root = NULL;
	if (is != NULL && ls != NULL && n > 0)
	{
		root = CreateIL(is, ls, n);
	}
	return root;
}

遍历字符串
1.层次遍历 == 心跳打印
/利用一个队列进行操作/

void NiceLevelOrder(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;
	}
}

2.“Z字形遍历”
/利用两个栈来进行操作/

void ZNiceLevelOrder(BtNode* ptr)
{
	if(ptr == NULL)
	{
		return ;
	}
	stack<BtNode*> lst;
	stack<BtNode*> rst;
	lst.push(ptr);
	while(!lst.empty() || !rst.empty())
	{
		while(!lst.empty())
		{
			ptr = lst.top();
			lst.pop();
			cout<<ptr->data<<" ";
			if(ptr->leftchild != NULL)
			{
				rst.push(ptr->leftchild);
			}
			if(ptr->rightchild != NULL)
			{
				rst.push(ptr->rightchild);
			}
		}
		while(!rst.empty())
		{
			ptr = rst.top();
			rst.pop();
			cout<<ptr->data<<" ";
			if(ptr->rightchild != NULL)
			{
				lst.push(ptr->rightchild);
			}
			if(ptr->leftchild != NULL)
			{
				lst.push(ptr->leftchild);
			}
		}
	}
	cout<<endl;
}

计算二叉树结点的个数

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

计算二叉树的深度

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

寻找某结点的值

法一:利用先序遍历进行寻找(比较)
BtNode* Findvalue(BtNode* ptr,ElemType val)
{
	if(root == NULL)
	{
		return NULL;
	}
	stack<BtNode*> st;
	st.push(ptr);
	while(!st.empty())
	{
		ptr = st.top();
		st.pop();
		if(ptr->data == val)
		{
			return ptr;
		}
		if(ptr->leftchild != NULL)
		{
			st.push(ptr->leftchild);
		}
		if(ptr->rightchild != NULL)
		{
			st.push(ptr->rightchild);
		}
	}
	return NULL;
}

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

判断是否为满二叉树

//法一:
bool Is_Full(BtNode* ptr)
{
	return (ptr == NULL) && Is_Full(ptr->leftchild) && Is_Full(ptr->rightchild) && Get_Depth(ptr->leftchild) == Get_Depth(ptr->rightchild);
}
//法二:
bool Is_Full_BinaryTree(BtNode* ptr)
{
	bool res = true;
	if(ptr == NULL)
	{
		return res;
	}
	queue<BtNode*> qu1,qu2;
	int n = 1;
	qu1.push(ptr);
	while(!qu1.empty() || !qu2.empty())
	{
		if(n != qu1.size())
		{
			res = false;
			break;
		}
		while(!qu1.empty())
		{
				BtNode* p = qu1.front();
				qu1.pop();
				if(p->leftchild != NULL)
				{
					qu2.push(p->leftchild);
				}
				if(p->rightchild != NULL)
				{
					qu2.push(p->rightchild);
				}
				n += n;
				if(n != qu2.size())
				{
					res = false;
					break;
				}
				while(!qu2.empty())
				{
					BtNode* p = qu2.front();
					qu2.pop();
					if(p->leftchild != NULL)
					{
						qu1.push(p->leftchild);
					}
					if(p->rightchild != NULL)
					{
						qu1.push(p->rightchild);
					}
				}
				n += n;
	   	}
	   	return res;
}

判断是否为完全二叉树

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

求最大路径和并输出路径

void PrintPath(BtNode* ptr,int val,vector<int>& vec)
{
	if(ptr == NULL)
	{
		return;
	}
	vec.push_back(ptr->data);
	if(ptr->leftchild == NULL && ptr->rightchild == NULL)
	{
		int sum = 0;
		for(int i = 0; i < vec.size(); i++)
		{
			sum += vec[i];
		}
		if(sum == val)
		{
			for(int i = 0; i < vec.size(); i++)
			{
				cout<<vec[i]<<" ";
			}
			cout<<endl;
		}
	}
	PrintPath(ptr->leftchild,val,vec);
	PrintPath(ptr->rightchild,val,vec);
	vec.pop_back();
}

将二叉搜索树变为二叉链表

//法一:利用非递归的中序遍历改成链式的过程
void CNiceInOrder(BtNode* ptr)
{
	if(ptr == NULL)
	{
		return ;
	}
	stack<BtNode*> st;
	BtNode* head = NULL:
	BtNode* nt = NULL;
	while(!st.empty() || ptr != NULL)
	{
		while(ptr != NULL)
		{
			st.push(ptr);
			ptr = ptr->leftchild;
		}
		ptr = st.top();
		st.pop();
		if(head == NULL)
		{
			head = ptr;
			nt = ptr;
		}
		else
		{
			nt->rightchild = ptr;
			ptr->leftchild = nt;
			nt = ptr;
		}
		ptr = ptr->rightchild;
	}
	cout<<endl;
}
//法二:利用递归的中序遍历改为链式
void InList(BtNode* ptr,BtNode*& pre,BtNode*& head)
{
	if(ptr != NULL)
	{
		InList(ptr->leftchild,pre);
		if(pre != NULL)
		{
			pre->rightchild = ptr;
			ptr->leftchild = pre;
		}
		else
		{
			head = ptr;
		}
		pre = ptr;
		InList(ptr->rightchild,pre,head);
	}
}
BtNode* InOrder_Lt(BtNode* ptr)
{
	if(ptr != NULL)
	{
		return NULL;
	}
	BtNode* pre = NULL;
	BtNode* head = NULL;
	InList(ptr,pre,head);
	return head;
}

//将二叉搜索树变成倒过来的链式存储

BtNode* RCNiceInOrder(BtNode* ptr)
{
	if(ptr == NULL)
	{
		return NULL;
	}
	stack<BtNode*> st;
	BtNode* head = NULL;
	BtNode* nt = NULL;
	while(!st.empty() || ptr != NULL)
	{
		while(ptr != NULL)
		{
			st.push(ptr);
			ptr = ptr->leftchild;
		}
		ptr = st.top();
		st.pop();
		if(head == NULL)
		{
			head = ptr;
		}
		else
		{
			nt = ptr->rightchild;
			head->leftchild = ptr;
			ptr->rightchild = head;
			head = ptr;
		}
		ptr = nt;
	}
	return head;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值