递归形式
递归形式遍历比较简单,不做详细论述。
前序遍历
void Preorder(treenode* root) //前序
{if (root != NULL){printf("%c", root->data);Preorder(root->left);Preorder(root->right);}
中序遍历
}
void Inorder(treenode* root) //中序
{if (root != NULL){ Inorder(root->left);printf("%c", root->data);Inorder(root->right);}}
后序遍历
void Postorder(treenode* root) //后序
{if (root != NULL){Postorder(root->left);Postorder(root->right);printf("%c", root->data);}
}
非递归形式
前序遍历
开始不断向左孩子遍历并入栈,在入栈的同时打印节点数据,直到左孩子为空,此时获取栈顶节点,并将其出栈,判断其有无右孩子,如果无右孩子,就再次获取栈顶节点并出栈,重复上述操作;如果有右孩子就将其入栈,并不断遍历其左孩子直到为空,重复上述操作,直到栈为空。
void PreOrder(treenode* root)
{if (root == NULL)return;treenode* p = root;stack<treenode *> s;while (!s.empty() || p){//边遍历边打印,并存入栈中while (p){printf("%c ", p->data);s.push(p);p = p->left;}//当p为空时,说明根和左子树都遍历完了,进入右子树if (!s.empty()){p = s.top();s.pop();p = p->right;}}
}
中序遍历
从根节点开始不断向左孩子遍历并入栈,直到为空,只要没有左孩子就出栈,在出栈的同时就打印节点数据,此时在判断出栈节点是否有右孩子,如果有右孩子重复上述操作继续向左孩子遍历,如果没有就出栈,重复上述操作判断有无右孩子,直到栈为空就退出遍历。
void InOrder(treenode* root)
{//空树if (root == NULL)return;//树非空treenode* p = root;stack<treenode *> s;while (!s.empty() || p){//一直遍历到左子树最下边,边遍历边保存根节点到栈中while (p){s.push(p);p = p->left;}//当p为空时,说明已经到达左子树最下边,这时需要出栈了if (!s.empty()){p = s.top();s.pop();printf("%c ", p->data);//进入右子树p = p->right;}}
}
后序遍历
后续在理解上较为难,用两个栈s1,s2更为直观,便于理解。
首先将根节点放入s2,再将其左右孩子放入s1中,一定要先放入左孩子,再放入右孩子,此时在获取s1栈顶节点并出栈,判断其是否有左右孩子,只要有孩子就将该节点入栈s2,并将该节点左右孩子放入s1中;如果该节点无左右孩子那么直接出栈s2并入栈s1,重复上述操作直到s1为空,在将s2从栈顶打印到栈底便是后续遍历
void PostOrder(treenode *root)
{stack<treenode *>s1, s2;treenode *cur=root; s1.push(cur);//入栈根节点while (!s1.empty()){cur = s1.top();//出栈s1入栈s2s1.pop();s2.push(cur);//判断是否有左右孩子,有则入栈s1if (cur->left)s1.push(cur->left);if (cur->right)s1.push(cur->right);}while (!s2.empty()){printf("%c ", s2.top()->data);//打印s2s2.pop();}
}
层序遍历
层序遍历需要用到队列,先入队根节点,在出队,将其左右孩子入队,依次出队入队操作,只要该节点有孩子就入队,再出队的同时打印节点数据
void sequence(treenode *root)
{deque<treenode *>q;treenode *cur = root;q.push_back(cur);//根节点入队while (!q.empty()){cur = q.front();//获取队头q.pop_front();printf("%c ", cur->data);//孩子入队if (cur->left)q.push_back(cur->left);if (cur->right)q.push_back(cur->right);}
}