下面关于二叉树三种遍历方法的前驱和后继作讨论和总结。 一、前序遍历 1.1 找后继: (1)若有左子女,则后继是左子女; (2)若无左子女,有右子女,则后继是右子女; (3)若既无左子女,又无右子女,则是一片叶子: a.若是其父母的左子女,且父母有右子女,则后继是父母的右子女。 b.若是其父母的左子女,且父母无右子女; c.若是其父母的右子女。 b、c都表示这是某个节点的左子树前序遍历的最后一个节点,则需要找第一个有右子树的“左祖先”(即找第一个使得当前节点在这个祖先的左子树上),然后后继就是这个祖先的右子女。 如何找这个左祖先?即 while( (p->parent->rchild==NULL||p->parent->rchild==p) && p!=NULL ) p=p->parent; if(!p)表示已经全部遍历完毕。结束;else p=p->lchild;下一个节点 1.2 找前驱 (1)若是父母的左孩子,则前驱是父母; (2)若是父母的右孩子,且父母无左子树,则前驱是父母; (3)若是父母的右孩子,父母有左子树,则前驱是父母左子树的最后访问到的节点(指向父母的左子树后,一直往右,若不行的话,往左一步,一直到叶子) 二、中序遍历 2.1 找后继 (1)如有右子女,后继是右子女的最左下节点; (2)若无右子女,且是父母的左子女,则后继就是父母; (3)若无右子女,且是父母的右子女,则一直上溯到第一个“左祖先”(定义如前面)则后继就是这个祖先。若无这样的祖先,说明已经遍历完毕。 2.2 找前驱 (1)如有左子女,前驱是左子女的最右下节点; (2)若无左子女,且是父母的右子女,则前驱就是父母; (3)若无左子女,且是父母的左子女,则一直上溯到第一个“右祖先”(定义如前面)则前驱就是这个祖先。若无这样的祖先,说明已经遍历完毕。 三、后序遍历 3.1 找后继 (1)若是父母的右孩子,则后继是父母; (2)若是父母的左孩子,且父母无右子树,则后继是父母; (3)若是父母的左孩子,父母有右子树,则后继是父母右子树的最先访问到的节点(指向父母的右子树后,一直往左,若不行的话,往右一步,一直到叶子) 3.2 找前驱: (1)若有右子女,则前驱是右子女; (2)若无右子女,有左子女,则前驱是左子女; (3)若既无左子女,又无右子女,则是一片叶子;再讨论: a.若是其父母的右子女,且父母有左子女,则前驱是父母的左子女。 b.若是其父母的右子女,且父母无左子女; c.若是其父母的左子女。 b、c都表示这是某个节点的右子树后序遍历的第一个节点,则需要找第一个 有 左子树的“右祖先”,然后前驱就是这个祖先的左子女。 其实前序遍历是“左右根”,中序遍历是“左根右”,后序是“左右根”,我们可以看出,前序找后继和后序找前驱是对偶的(只要把左换成右,前驱换成后继,第一访换成最后访问即可),同样前序找前驱和后序找后继,中序找前驱和中序找后继都是对偶的,这样记忆起来就非常方便了~~~~~ 附上中序遍历查找前驱后后继的代码:
- typedef struct _node {
- struct _node *left_child;
- struct _node *right_child;
- struct _node * parent;
- ctype data;
- }node; //树节点数据结构定义
- typedef node* Tree;
- //查找二叉查找树中关键字最小的节点,返回指向该节点的指针
- Tree tree_minimum(Tree root)
- {
- Tree p = root;
- while (p->left_child != null)
- p = p->left_child;
- return p;
- }
- //查找二叉查找树中关键字最大的节点,返回指向该节点的指针
- Tree tree_maxmum(Tree root)
- {
- Tree p = root;
- while (p->right_child != null)
- {
- p = p->right_child;
- }
- return p;
- }
- //查找二叉查找树中节点x的后继节点,返回指向该节点的指针
- //在查找过程中,如果节点x右子树不为空,那么返回右子树的最小节点即可
- //如果节点x的右子树为空,那么后继节点为x的某一个祖先节点的父节点,而且该祖先节点是作为其父节点的左儿子
- Tree tree_successor(Tree x)
- {
- if (x->right_child != null)
- return tree_minimum(x->right_child);
- //x用来保存待确定的节点
- //y为x的父节点
- Tree y = x->parent;
- while (y != NULL && x == y->right_child)
- {
- x = y;
- y = y->parent;
- }
- return y;
- }
- //查找二叉查找树中节点x的前驱节点,返回指向该节点的指针
- //在查找过程中,如果节点x左子树不为空,那么返回左子树的最大节点即可
- //如果节点x的左子树为空,那么前驱节点为x的某一个祖先节点的父节点,而且该祖先节点是作为其父节点的右儿子
- Tree tree_predecessor(Tree x)
- {
- if (x->left_child != null)
- return tree_maxmum(x->left_child);
- Tree y = x->parent;
- while (y != NULL && x == y->left_child)
- {
- x = y;
- y = y->parent;
- }
- return y;
- }
二叉树遍历的前驱和后继
最新推荐文章于 2024-06-24 19:58:59 发布