C++二叉树各种常用遍历算法总结

264 阅读4分钟

在学习二叉树的过程中对基于遍历算法设计的各种常用函数做一个归纳,函数中都使用了递归的思想,以二叉树的前序遍历、中序遍历和后序遍历为思路,在递归遍历的过程中完成对二叉树的各种简单操作。特在此记录,以便后续回顾复习。

#pragma once

typedef char ElemType;
#define MaxSize 20
#include <iostream>
typedef struct BTNode
{
	ElemType data;
	struct BTNode* lchild;
	struct BTNode* rchild;
};

void CreatBTree(BTNode*& b, char* str)       //二叉树构造
{
	BTNode* St[MaxSize], * p = (BTNode*)malloc(sizeof(BTNode));
	int top = -1, k, j = 0;
	char ch;
	b = NULL;
	ch = str[j];
	while (ch != '\0')
	{
		switch (ch)
		{
		case '(':top++; St[top] = p; k = 1; break;
		case ')':top--; break;
		case',':k = 2; break;
		default: p = (BTNode*)malloc(sizeof(BTNode));
			p->data = ch;
			p->lchild = p->rchild = NULL;
			if (b == NULL)
				b = p;
			else
			{
				switch (k)
				{
				case 1:St[top]->lchild = p; break;
				case 2:St[top]->rchild = p; break;
				}
			}
		
		}
		ch = str[++j];
	}
}

void DestoryBTree(BTNode*& b)           //二叉树析构
{
	if (b != NULL)
	{
		DestoryBTree(b->lchild);
		DestoryBTree(b->rchild);
		free(b);
	}
}

BTNode* FindNode(BTNode* b, ElemType x)     //先序遍历寻找第一个值为x的结点
{
	BTNode* p;
	if (b == NULL)
		return NULL;
	else if (b->data == x)
		return b;
	else
	{
		p = FindNode(b->lchild, x);
		if (p != NULL)
			return p;
		else
			return FindNode(b->rchild, x);
	}
}

int BTHeight(BTNode* b)                   //求树高
{
	int lchildh, rchild;
	if (b == NULL)
		return 0;
	else
	{
		lchildh = BTHeight(b->lchild);
		rchild = BTHeight(b->rchild);
		return (lchildh > rchild) ? (lchildh + 1) : (rchild + 1);
	}
}

void DispBTree(BTNode*b)                  //括号表达式输出二叉树
{
	if (b != NULL)
	{
		std::cout << b->data;
		if (b->lchild != NULL || b->rchild != NULL)
		{
			std::cout << '(';
			DispBTree(b->lchild);
			if (b->rchild != NULL) std::cout << ',';
			DispBTree(b->rchild);
			std::cout << ')';
		}
	}
}

int Nodes(BTNode* b)                   //二叉树结点总数
{
	if (b == NULL)
		return 0;
	else
		return Nodes(b->lchild) + Nodes(b->rchild) + 1;
}

void DispLeaf(BTNode* b)                  //输出所有叶子结点
{
	if (b != NULL)
	{
		if (b->lchild == NULL && b->rchild == NULL)
			std::cout << b->data;
		else
		{
			DispLeaf(b->lchild);
			DispLeaf(b->rchild);
		}
	}
}

int Level(BTNode* b, ElemType x, int h=1)   //先序遍历查找第一个值为x的结点所在层数
{
	if (b == NULL)
		return 0;
	else
	{
		if (b->data == x)
			return h;
		else
		{
			int l = Level(b->lchild, x, h + 1);
			if (l == 0)
				return Level(b->rchild, x, h + 1);
			else
				return l;
		}
	}
}

void Lnodenum(BTNode* b, int k, int& n,int h=1 )   //第k层节点总数
{
	if (b == NULL) return ;
	else
	{
		if (h == k) n++;
		else if (h < k)
		{
			Lnodenum(b->lchild, k, n, h + 1);
			Lnodenum(b->rchild, k, n, h + 1);
		}
	}
}

bool Like(BTNode* b1, BTNode* b2)        //判断两棵树是否相似
{
	bool like1, like2;
	if (b1 == NULL && b2 == NULL)
		return  true;
	else if (b1 == NULL || b2 == NULL)
		return false;
	else
	{
		like1 = Like(b1->lchild, b2->lchild);
		like2 = Like(b1->rchild, b2->rchild);
		return like1 && like2;
	}
}

bool DispAncestor(BTNode* b, ElemType x)     //输出结点的所有祖先节点
{
	if (b == NULL)
		return false;
	else if (b->lchild != NULL && b->lchild->data == x
		|| b->rchild != NULL && b->rchild->data == x)
	{
		std::cout << b->data;
		return true;
	}
	else if (DispAncestor(b->lchild, x) || DispAncestor(b->rchild, x))
	{
		std::cout << b->data;
		return true;
	}
	else return false;
}

int LeafNodes(BTNode* b)             //求二叉树叶子节点个数
{
	int n1, n2;
	if (b == NULL)
		return 0;
	else
	{
		if (b->lchild == NULL && b->rchild == NULL)
			return 1;
		else
			return LeafNodes(b->lchild) + LeafNodes(b->rchild);
	}
}

int D1Nodes(BTNode* b)                  //度数为1的结点总数
{
	if (b == NULL)
		return 0;
	else if (b->lchild != NULL && b->rchild == NULL)
		return D1Nodes(b->lchild) + 1;
	else if (b->rchild != NULL && b->rchild == NULL)
		return D1Nodes(b->rchild) + 1;
	else
		return D1Nodes(b->lchild) + D1Nodes(b->rchild);
}

int D2Nodes(BTNode* b)               //度数为2的节点总数
{
	if (b == NULL)
		return 0;
	int n = D2Nodes(b->lchild) + D2Nodes(b->rchild);
	if (b->lchild != NULL && b->rchild != NULL)
		return n + 1;
	else
		return n;
}

int CountK(BTNode* b, ElemType k)     //值为k的结点个数
{
	if (b == NULL)
		return 0;
	else if (b->data == k)           //可以换成D2Nodes的写法
		return CountK(b->lchild, k) + CountK(b->rchild, k) + 1;
	else
		return CountK(b->lchild, k) + CountK(b->rchild, k);
}

void Min(BTNode* b, ElemType& x, BTNode*& p)    //求二叉树值最小的结点
{												//功能函数
	if (b != NULL)
	{
		if (b->data < x)
		{
			x = b->data;
			p = b;
		}
		Min(b->lchild, x, p);
		Min(b->rchild, x, p);
	}
}

BTNode* Min(BTNode* t)						//求二叉树值最小的结点
{											//接口函数
	ElemType x = t->data;
	BTNode* p = t;
	Min(t, x, p);
	return p;
}

void Copy(BTNode* b, BTNode*& t)           //辅助二叉树
{											
	if (b == NULL)
		t = NULL;
	else
	{
		t = (BTNode*)malloc(sizeof(BTNode));
		t->data = b->data;
		Copy(b->lchild, t->lchild);
		Copy(b->rchild, t->rchild);
	}
}

void Swap(BTNode* b, BTNode*& t)              //交换二叉树的左右子树
{
	if (b == NULL)
		t = NULL;
	else
	{
		t = (BTNode*)malloc(sizeof(BTNode));
		t->data = b->data;
		Swap(b->lchild, t->rchild);
		Swap(b->rchild, t->lchild);
	}
}