利用队列实现层序遍历
广度优先遍历
void LevelOrder(Node *root) {
if (root == NULL) {
printf("\n");
}
// 启动
std::queue<Node *> q;
q.push(root);
while (!q.empty()) {
Node *front = q.front();
q.pop();
printf("%c ", front->value);
if (front->left != NULL) {
q.push(front->left);
}
if (front->right != NULL) {
q.push(front->right);
}
}
printf("\n");
}
判断是否为完全二叉树
bool IsComplete(Node *root) {
std::queue<Node *> q;
q.push(root);
while (true) {
Node *front = q.front();
q.pop();
if (front == NULL) {
break;
}
// 层序遍历,空结点也进队列
q.push(front->left);
q.push(front->right);
}
// 判定队列中剩余数据是否全是 NULL
while (!q.empty()) {
Node *front = q.front();
q.pop();
if (front != NULL) {
return false;
}
}
// 所有都是 NULL
return true;
}
测试代码
void Test1() {
char *inorder = "DBEAC";
char *postorder = "DEBCA";
int size = strlen(inorder);
Node *root = buildTree2(inorder, postorder, size);
LevelOrder(root);
if (IsComplete(root)) {
printf("是完全二叉树\n");
}
else {
printf("不是完全二叉树\n");
}
}
用栈实现前、中、后序(非递归方式)
栈实现前序
void PreOrderNoR(Node *root) {
std::stack<Node *> s;
Node *cur = root;
while (cur != NULL || !s.empty()) { //一开始栈为空,cur不为空
while (cur != NULL) {
printf("%c ", cur->value);
s.push(cur);
cur = cur->left;
}
Node *top = s.top(); s.pop();
cur = top->right;
}
}
测试代码
void Test2() {
char *inorder = "DBEAC";
char *postorder = "DEBCA";
int size = strlen(inorder);
Node *root = buildTree2(inorder, postorder, size);
PreOrderNoR(root);
}
栈实现中序
void InOrderNoR(Node *root) {
std::stack<Node *> s;
Node *cur = root;
while (cur != NULL || !s.empty()) {
while (cur != NULL) {
s.push(cur); //第一次遇到结点
cur = cur->left;
}
Node *top = s.top(); s.pop();
printf("%c ", top->value); //第二次遇到结点
cur = top->right;
}
}
栈实现后序
void PostOrderNoR(Node *root) {
std::stack<Node *> s;
Node *cur = root;
Node *last = NULL;
while (cur != NULL || !s.empty()) {
while (cur != NULL) {
// 第一次遇到
s.push(cur);
cur = cur->left;
}
Node *top = s.top();
// 不知道是第二次遇到还是第三次遇到
if (top->right == NULL) { //右孩子为空,说明右子树也为空,不进行右子树的遍历【2、3次遇到】
printf("%c ", top->value); //打印,表示这个结点遍历完了,直接出栈
s.pop();
last = top;
}
else if (top->right == last) { //【第三次遇到】
printf("%c ", top->value);
s.pop();
last = top;
}
else { //从左边过来的,右子树没有遍历过,【第二次遇到】
cur = top->right;
}
}
}
注意,无论某一结点时,栈内存的数据总是:从根到该结点的路径。