按照某条搜索路径访问树中每个结点,使得每个结点均被访问。主要分为先序遍历,中序遍历,后序遍历,层序遍历
考试一般给一个树的形状,写出他的先序遍历
void PreOrder(BiTree T){ if(T!=NULL) visit(T);//访问根结点 PreOrder(T->lchild); //递归遍历左子树 PreOrder(T->rchild); //递归遍历右子树 }
void PreOrder2(BiTree T){ InitStack(S);//初始化栈S; BiTree p = T;//初始化p是遍历指针 while(p||!IsEmpty(S)){ //栈不空或p不空时循环 if(p){ //一路向左 visit(p); //访问当前结点 Push(S,p); //当前结点入栈 p=p->lchild; //左孩子不空,一直往左走 } else{ //出栈,并转向栈结点的右子树 Pop(S,p); //栈顶元素出栈 p=p->rchild;//向右子树走,p赋值为当前结点的右孩子 } //返回while循环继续进入if-else语句 } }
void InOrder(BiTree T){ if(T!=NULL) InOrder(T->lchild); //递归遍历左子树 visit(T);//访问根结点 InOrder(T->rchild); //递归遍历右子树 }
void InOrder2(BiTree T){ InitStack(S);//初始化栈S; BiTree p = T;//初始化p是遍历指针 while(p||!IsEmpty(S)){ //栈不空或p不空时循环 if(p){ //一路向左 Push(S,p); //当前结点入栈 p=p->lchild; //左孩子不空,一直往左走 } else{ //出栈,并转向栈结点的右子树 Pop(S,p); //栈顶元素出栈 visit(p); //访问出栈结点 p=p->rchild;//向右子树走,p赋值为当前结点的右孩子 } //返回while循环继续进入if-else语句 } }
void PostOrder(BiTree T){ if(T!=NULL) visit(T);//访问根结点 PostOrder(T->lchild); //递归遍历左子树 PostOrder(T->rchild); //递归遍历右子树 }
void PostOrder2(BiTree T){ InitStack(S);//初始化栈S; BiTree p = T;//初始化p是遍历指针 while(p||!IsEmpty(S)){ //栈不空或p不空时循环 if(p){ //一路向左 Push(S,p); //当前结点入栈 p=p->lchild; //左孩子不空,一直往左走 } else{ //向右 GetTop(S,p); //读栈顶结点(非出栈) if(p->rchild &&p->rchild!=r) //若右子树存在,且未被访问过 p = p->rchild; //转向右 else{ //否则,弹出结点并访问 pop(S,p); //将结点弹出 visit(p->data); //访问该结点 r = p; //记录最近访问过的结点 p=NULL; //结点访问完后,重置p指针 } //else } //while }
void LevelOrder(BiTree T){ InitQueue(Q); //初始化辅助队列 BiTree p; EnQueue(Q,T); //将根结点入队 while(!IsEmpty (Q)){//队列不空则循环 DeQueue(Q,p);//队头结点出队 visit(p); //访问出队结点 if(p->lchild !=NULL) //左子树不空,则左子树根结点入队 EnQueue(Q,p->lchild); if(p->rchild !=NULL) //右子树不空,则右子树根结点入队 EnQueue(Q,p->lchild); } }
中序遍历+前,后,层序遍历中的任何一个即可构成二叉树。
考试经常会给出两个序列(其中有一个必定时中序遍历)然后画出一个二叉树或者再推另外一个遍历
typedef struct ThreadNode{ ElemType data; struct ThreadNode *lchild,*rchild;//左右孩子指针 int ltag,rtag; //左右线索标志0表孩子,1表示指针 }ThreadNode,*ThreadTree;
经典例题,这题会了基本上可以解决大部分手算题目
在这里插入代码片