遍历二叉树
二叉树是由3个基本单元组成的:根节点、左子树和右子树。因此,若遍历了这三个部分,便是遍历了整个二叉树。假如以L、D、R分别表示遍历左子树、访问根节点、遍历右子树,则一共有DLR、LDR、LRD、DRL、RDL、RLD这6种遍历二叉树的方案。若限定先左后右,则只有前3中情况,分别称之为先(根)序遍历、中(根)序遍历、后(根)序遍历。
先序遍历:
若二叉树为空,则空操作;否则
(1)访问根节点;
(2)先序遍历左子树;
(3)先序遍历右子树;
非递归:
1 void preorder(BiTree t){ 2 seqstack s; 3 s.top = -1; //因为top在这里表示了数组中的位置,所以空为-1 4 if(!t){ 5 printf("the tree is empty\n"); 6 }else{ 7 while(t || s.stop != -1){ 8 while(t){ //只要结点不为空就应该入栈保存,与其左右结点无关 9 printf("%c ",t->data); 10 push(&s,t); 11 t= t->lchild; 12 } 13 t=pop(&s); 14 t=t->rchild; 15 } 16 } 17 }
递归:
1 void PreOrder(BiTree t) 2 { 3 if(t == NULL) 4 { 5 return; 6 } 7 8 printf("%c ", t->data) 9 PreOrder(root->lchild); 10 PreOrder(root->rchild); 11 12 }
中序遍历:
若二叉树为空,则空操作;否则
(1)中序遍历左子树;
(2)访问根节点;
(3)中序遍历右子树;
非递归:
1 void midorder(BiTree t){ 2 seqstack s; 3 s.top = -1; 4 if(!t){ 5 printf("the tree is empty!\n"); 6 }else{ 7 while(t ||s.top != -1){ 8 while(t){ 9 push(&s,t); 10 t= t->lchild; 11 } 12 t=pop(&s); 13 printf("%c ",t->data); 14 t=t->rchild; 15 } 16 } 17 }
递归:
1 void InOrder(BiTree t) 2 { 3 4 if(r == NULL) 5 { 6 return; 7 } 8 9 InOrder(root->left); 10 printf("%c ", t->data); 11 InOrder(root->right); 12 13 }
后序遍历:
若二叉树为空,则空操作;否则
(1)后序遍历左子树;
(2)后序遍历右子树;
(3)访问根节点;
非递归:
1 void postorder(BiTree t){ 2 seqstack s; 3 s.top = -1; 4 if(!t){ 5 printf("the tree is empty!\n"); 6 }else{ 7 while(t || s.top != -1){ //栈空了的同时t也为空。 8 while(t){ 9 push(&s,t); 10 s.tag[s.top] = 0; //设置访问标记,0为第一次访问,1为第二次访问 11 t= t->lchild; 12 } 13 if(s.tag[s.top] == 0){ //第一次访问时,转向同层右结点 14 t= s.data[s.top]; //左走到底时t是为空的,必须有这步! 15 s.tag[s.top]=1; 16 t=t->rchild; 17 }else { 18 while (s.tag[s.top] == 1){ //找到栈中下一个第一次访问的结点,退出循环时并没有pop所以为其左子结点 19 t = pop(&s); 20 printf("%c ",t->data); 21 } 22 t = NULL; //必须将t置空。跳过向左走,直接向右走 23 } 24 } 25 } 26 }
递归:
1 void PostOrder(BiTree t) 2 { 3 if(t == NULL) 4 { 5 return; 6 } 7 8 PostOrder(root->left); 9 PostOrder(root->right); 10 printf("%c ", t->data); 11 12 }
浙公网安备 33010602011771号