二叉树基础函数--C++实现

一、二叉树的先序创建

二叉树的先序创建,首先要构建的根结点,然后依次构建其左孩子和右孩子,根据递归的的思想,孩子结点会再次作为子树的根结点传入先序创建函数中。

void CreateBiTree(BiTree& T)//先序创建树
{
	char ch;
	cin >> ch;
	if (ch == '*') T = NULL;
	else
	{
		T = new BiTNode;
		T->date = ch;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild);
	}
}

二、二叉树的遍历

二叉树的先序遍历,将根结点传入函数中,输出该结点的数据,依次访问左孩子和右孩子,根据递归的的思想,再将左、右孩子作为根节点;
中序遍历,先访问节点的左孩子,再输出此时子树根节点的数据,再访问右孩子,依次递归下去;
同理,后序遍历是将输出子树根结点的数据放到了,访问左右子树的最后。

(1)先序遍历

void PreOrderTraverse(BiTree T)//先序遍历
{
	if (T)
	{
		cout << T->date << " ";
		PreOrderTraverse(T->lchild);
		PreOrderTraverse(T->rchild);
	}
}

(2)中序遍历

void InOrderTraverse(BiTree T)//中序遍历
{
	if (T)
	{
		InOrderTraverse(T->lchild);
		cout << T->date << " ";
		InOrderTraverse(T->rchild);
	}
}

(3)后序遍历

void PostOrderTraverse(BiTree T)//后序遍历
{
	if (T)
	{
		PostOrderTraverse(T->lchild);
		PostOrderTraverse(T->rchild);
		cout << T->date << " ";
	}
}

(4)逐层遍历

void LevelOrderTraverse(BiTree T)//逐层遍历
{
	BiTree Q[100];
	int front = 0, rear = 0;
	BiTree p;
	if (T)
	{
		Q[rear] = T;//根结点入队
		rear = (rear + 1) % 100;
	}
	while (front != rear)
	{
		p = Q[front];  //队头元素出队
		front = (front + 1) % 100;
		printf("%c ", p->date);
		if (p->lchild)//左孩子不为空,入队
		{
			Q[rear] = p->lchild;
			rear = (rear + 1) % 100;
		}
		if (p->rchild)//右孩子不为空,入队
		{
			Q[rear] = p->rchild;
			rear = (rear + 1) % 100;
		}
	}
}

三、其他应用函数

(1)求二叉树的深度

int Depth(BiTree T)//求树的深度
{
	if (T == NULL)
	{
		return 0;
	}
	else
	{
		int m = Depth(T->lchild);
		int n = Depth(T->rchild);
		if (m > n) return (m + 1);
		else return (n + 1);
	}
}

(2)复制二叉树

void Copy(BiTree T, BiTree& NewT)//复制树
{
	if (T == NULL)
	{
		NewT = NULL;
		return;
	}
	else
	{
		NewT = new BiTNode;
		NewT->date = T->date;
		Copy(T->lchild, NewT->lchild);
		Copy(T->rchild, NewT->rchild);
	}
}

(3)统计结点数

int NodeCount(BiTree T)//统计结点数
{
	if (T == NULL) return 0;
	else return NodeCount(T->lchild) + NodeCount(T->rchild) + 1;
}

(4)统计叶子结点数

int LeafCount(BiTree T)//统计叶子结点数
{
	if (!T) return 0;
	if (!T->lchild && !T->rchild)
	{
		return 1;
	}
	else
	{
		return LeafCount(T->lchild) + LeafCount(T->rchild);
	}
}

(5)打印从叶子结点到根结点的路径

void PrintAllPath(BiTree T, char path[], int pathlen)//打印从叶子结点到根结点的路径
{
	int i;
	if (T != NULL)
	{
		path[pathlen] = T->date;
		if (T->lchild == NULL && T->rchild == NULL)
		{
			for (i = pathlen; i >= 0; i--)
			{
				cout << path[i];
			}
			cout << endl;
		}
		else
		{
			PrintAllPath(T->lchild, path, pathlen + 1);
			PrintAllPath(T->rchild, path, pathlen + 1);
		}
	}
}

!!!
应用该函数主函数,代码如下:

int main()
{
	char path[256];
	int pathlen = 0;
	PrintAllPath(T, path, pathlen);
}

(6)左右结点交换

void ExChangeTree(BiTree& T)//左右结点交换
{
	BiTree temp;
	if (T != NULL)
	{
		temp = T->lchild;
		T->lchild = T->rchild;
		T->rchild = temp;
		ExChangeTree(T->lchild);
		ExChangeTree(T->rchild);
	}
}

(6)删除结点

void dete(BiTree &T, char e)//删除结点
{
	if (T == NULL)
	{
		return;
	}
	if (T->date == e)
	{
		T = NULL;
	}
	if (T != NULL)
	{
		dete(T->lchild, e);
		dete(T->rchild, e);
	}
}

(7)求位于先序序列中第k个位置的结点的值

bool Find_K(BiTree T, int* i, int k)//求位于先序序列中第k个位置的结点的值
 {
	if (T == NULL) return false;
	(*i)++;
	if (k == *i) {
		printf("%c\n", T->date);
		return true;
	}
	if (Find_K(T->lchild, i, k) || Find_K(T->rchild, i, k))
		return true;
	return false;
}

(8)计算层数节点数

int printNodeAtLevel(BiTree root, int level, int& count)//计算层数节点数 
{
	if (!root || level < 0)
		return 0;
	if (0 == level) 
	{
		count++;
		return 1;
	}
	return printNodeAtLevel(root->lchild, level - 1, count) + printNodeAtLevel(root->rchild, level - 1, count);
}

四、具体问题

(1)创建哈夫曼树并计算带权路径长度

#include <iostream>
#include <cstdio>
using namespace std;

struct TreeNode
{
	int value;
	TreeNode* lchild, * rchild;
};

TreeNode* creat(int a[], int n)
{
	TreeNode* store[30] = { NULL };
	TreeNode* temp;
	temp = new TreeNode;
	for (int j = 0; j < n; j++)
	{
		temp->value = a[j];
		temp->lchild = NULL;
		temp->rchild = NULL;
		store[j] = temp;
		temp = new TreeNode;
	}
	TreeNode* p = NULL;
	while (1)
	{
		int min1 = 0, min2 = 0;
		int count = 0;
		for (int j = 0; j < n; j++)
		{
			if (store[0] == NULL)
			{
				min1 = 1;
			}
			if (store[j] != NULL)
			{
				if (store[min1]->value > store[j]->value)
				{
					min1 = j;
				}
			}
		}
		if (min1 == 0)
		{
			min2 = 1;
		}
		for (int j = 0; j < n; j++)
		{
			if (j == min1)
			{
				continue;
			}
			if (store[min2] == NULL && min2 <= j)
			{
				min2++;
			}
			if (store[j] != NULL && store[min2] != NULL)
			{
				if (store[min2]->value > store[j]->value)
				{
					min2 = j;
				}
			}
		}
		temp = new TreeNode;
		temp->value = store[min1]->value + store[min2]->value;
		temp->lchild = store[min1];
		temp->rchild = store[min2];
		store[min1] = temp;
		store[min2] = NULL;
		for (int j = 0; j < n; j++)
		{
			if (store[j] != NULL)
			{
				p = store[j];
				count++;
			}
		}
		if (count == 1)
		{
			return p;
		}
	}
}

int W(TreeNode* T, int len)
{
	TreeNode* p = T;
	if (p == NULL)
	{
		return 0;
	}
	else
	{
		if (!p->lchild && !p->rchild)
		{
			return len * p->value;
		}
		else
		{
			return W(p->lchild, len + 1) + W(p->rchild, len + 1);
		}
	}
}

int main()
{
	TreeNode* tree;
	int a[10], i = 0;
	char c;
	while (1)
	{
		c = getchar();
		if (c == '\n')
		{
			break;
		}
		else if (c != ' ')
		{
			a[i++] = c - '0';
		}
		else
		{
			continue;
		}
	}
	tree = creat(a, i);
	int wpl;
	int len = 0;
	wpl = W(tree, len);
	cout << wpl;
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值