二叉树的层序遍历,按从上往下,从左往右的顺序遍历二叉树。同一行的兄弟、堂兄弟节点之间,没有直接必然的连接关系。所以我们很难根据同一行中的一个节点来确定同行中其他节点的是否存在,节点位置在哪里。这里我们采用了顺序队列来辅助解决这个问题。因为队列里面的数组成员有记忆保存功能。我们可以用队列来保存二叉树里的一行所有节点。比如根节点只有一个,把根节点入队列,就相当于保存了第一行所有节点。遍历第一行节点的两个根节点,若存在,则也输入队列。以此类推。当我们逐个输出队列里某一行的节点时,同时考察节点是否有子节点,有的话也入队列,当本行输出完毕,我们也在队列里存入了下一行所有节点。所以实现了二叉树的层序遍历。
如果检测到某个节点是叶子节点,我们就可以输出该叶子节点到根节点的路径。此时队列的数组成员的元素应该是结构体变量,既包含二叉树节点,还应保存其父母节点的数组下标,以便于能在队列数组里找到其父母节点,以输出整个路径。
完整代码如下(包含建立二叉树createBTree、输出二叉树displayBTree、层序遍历二叉树查找所有从叶节点到根节点的路径findAllPath三个函数:):
#include<iostream>
#include<stdio.h>
using namespace std;
#define STACKDEPTH 15
#define QUEUELENGTH 50
struct BiTreeNode {
char value;
BiTreeNode* leftChild;
BiTreeNode* rightChild;
};
struct Step {
BiTreeNode* node;
int indexFront;
};
struct Queue {
Step steps[QUEUELENGTH];
int indexHead = 0;
int indexTail = 0;
};
void createBTree(BiTreeNode *&biTreeRoot,char *&ptChar) {
struct {
BiTreeNode* ptsBiTree[STACKDEPTH];
int indexTop = -1;
}sequStack;
BiTreeNode* ptNew = NULL;
char s ;
int leftRight;//1 is left 2 is right
while (*ptChar != '\0') {
s = *ptChar;
if ('A' <= s && s <= 'Z') {
ptNew = new BiTreeNode;
ptNew->value = s;
ptNew->leftChild = ptNew->rightChild = NULL;
if (biTreeRoot == NULL)
biTreeRoot = ptNew;
else if (leftRight == 1)
sequStack.ptsBiTree[sequStack.indexTop]->leftChild = ptNew;
else if (leftRight == 2)
sequStack.ptsBiTree[sequStack.indexTop]->rightChild = ptNew;
}
else if (s == '(') {
sequStack.indexTop++;
sequStack.ptsBiTree[sequStack.indexTop] = ptNew;
leftRight = 1;
}
else if (s == ',')
leftRight = 2;
else if (s == ')')
sequStack.indexTop--;
ptChar++;
}
}
void displayBTree(BiTreeNode *&biTreeRoot) { // 本查找方法是先序遍历
if (biTreeRoot == NULL)
return;//if binary tree does not exsit,return
cout << biTreeRoot->value;
if (biTreeRoot->leftChild != NULL || biTreeRoot->rightChild != NULL) {
cout << '(';
displayBTree(biTreeRoot->leftChild);
if (biTreeRoot->rightChild != NULL) {
cout << ',';
displayBTree(biTreeRoot->rightChild);
}
cout << ')';
}
}
void findAllPath(BiTreeNode*& biTreeRoot) {
if (biTreeRoot == NULL) {
cout << endl << "empty tree ." << endl;
return;
}
Queue queue;
queue.steps[0].node = biTreeRoot;
Step stepHead;
int countPath = 0;
while (queue.indexHead <= queue.indexTail) {
stepHead = queue.steps[queue.indexHead];
if (stepHead.node->leftChild == NULL && stepHead.node->rightChild == NULL) {
countPath++;
cout <<"the " << countPath << "th path : ";
for (int i = queue.indexHead; i >= 0;) {
cout << queue.steps[i].node->value << ' ';
i = queue.steps[i].indexFront;
}
cout<<endl;
}
else {
if (stepHead.node->leftChild != NULL) {
queue.indexTail++;
queue.steps[queue.indexTail].node = stepHead.node->leftChild;
queue.steps[queue.indexTail].indexFront = queue.indexHead;
}
if (stepHead.node->rightChild != NULL) {
queue.indexTail++;
queue.steps[queue.indexTail].node = stepHead.node->rightChild;
queue.steps[queue.indexTail].indexFront = queue.indexHead;
}
}
queue.indexHead++;
}
}
int main() {
char array[] = "A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))";
char* ptChar = array; //c++里只能这样分开定义,要不会出错。
BiTreeNode* biTreeRoot = NULL;
createBTree(biTreeRoot,ptChar);
cout << "the char array is :";
for (int i = 0; array[i] != '\0'; i++)
cout << array[i];
cout<< endl<< "binary tree is :";
displayBTree(biTreeRoot);
cout << endl;
findAllPath(biTreeRoot);
return 0;
}
测试代码和对应二叉树如下:
谢谢阅读