二叉树基础函数--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;
}