一、前序遍历
前序遍历简单来讲,遍历顺序是:根节点-左子树-右子树
1、递归遍历
1 void preorder(BinTree *T) 2 { 3 if(T==NULL) 4 return; 5 cout << T->data; 6 preorder(T->left); 7 preorder(T->right); 8 }
2、迭代遍历(用栈实现)
1 void preorder2(BinTree *T) 2 { 3 //空树,直接返回 4 if(T==NULL) 5 return; 6 //定义一个存放二叉树节点的栈结构 7 stacks; 8 BinTree *pcur; 9 pcur = T; 10 //循环遍历二叉树直到根节点为空或者栈为空 11 while (pcur || !s.empty()) 12 { 13 if (pcur) 14 { 15 cout << pcur->data; 16 s.push(pcur); 17 pcur = pcur->left; 18 }else 19 { 20 //当根节点为空时,说明左子树已遍历完,通过取出栈顶结点,来访问根节点的右子树 21 pcur = s.top(); 22 s.pop(); 23 pcur = pcur->right; 24 } 25 } 26 }
二、中序遍历
遍历顺序是:左子树-根节点-右子树
1、递归遍历
1 void inoeder(BinTree *T) 2 { 3 if(T == NULL) 4 return; 5 inoeder(T->left); 6 cout << T->data; 7 inoeder(T->right); 8 }
2、迭代遍历(用栈实现)
1 void inorder2(BinTree *T) 2 { 3 if(T == NULL) 4 return; 5 stacks; 6 BinTree *pcur; 7 pcur = T; 8 while (pcur || !s.empty()) 9 { 10 if (pcur) 11 { 12 //根节点非空,入栈,继续遍历左子树直到根节点为空 13 s.push(pcur); 14 pcur = pcur->left; 15 }else 16 { 17 //根节点为空,说明左子树已经遍历完,弹出根节点打印,通过根节点访问右子树 18 pcur = s.top(); 19 s.pop(); 20 cout << pcur->data; 21 pcur = pcur->right; 22 } 23 } 24 }
三、后序遍历
遍历顺序:左子树-右子树-根节点
1、递归遍历
1 void postorder(BinTree *T) 2 { 3 if (T==NULL) 4 return; 5 postorder(T->left); 6 postorder(T->right); 7 cout << T->data; 8 }
2、迭代遍历(用栈实现)
1 void postorder2(BinTree *T) 2 { 3 if(T == NULL) 4 return; 5 stacks; 6 s.push(T); 7 BinTree *pcur; 8 pcur = NULL; 9 while (!s.empty()) 10 { 11 pcur = s.top(); 12 if (pcur->left == NULL && pcur->right == NULL) 13 { 14 cout << pcur->data; 15 s.pop(); 16 }else 17 { 18 //注意右孩子先入栈左孩子后入栈,这样再次循环时左孩子节点才先出栈 19 if(pcur->right) 20 { 21 s.push(pcur->right); 22 pcur->right = NULL; 23 } 24 if (pcur->left) 25 { 26 s.push(pcur->left); 27 pcur->left = NULL; 28 } 29 } 30 } 31 }
四、层序遍历
层序遍历是图的广度优先搜索的应用,常用队列结构实现
1.迭代遍历
关键点:根节点一出队列,就要判断其左右孩子是否为空,若不为空的话依次入队列
1 void leveltraversal(BinTree *T) 2 { 3 queues; 4 s.push(T); 5 BinTree* pcur; 6 while (!s.empty()) 7 { 8 pcur=s.front(); 9 cout< data; 10 s.pop(); 11 if (pcur->left) 12 { 13 s.push(pcur->left); 14 } 15 if (pcur->right) 16 { 17 s.push(pcur->right); 18 } 19 } 20 }
2、分层遍历二叉树,即从上到下按层次访问该树,每一层单独输出一行
思想:定义两个变量last,nlast,last代表正在打印的当前行的最右节点,nlast代表目前出现的进入队列的最右节点(下一行节点),nlast跟踪的是队列中加入的节点。
last等于节点1,1入队列,打印1并弹出1,将1的左右孩子放入队列,2入队列,并让nlast等于节点2,3入队列并让nlast等于节点3,此时发现last与之前出队列的1节点相等,换行,并将nlast赋给last(等于节点3)。
接下来,节点2出栈,打印节点2,并让结点2的孩子进入队列,节点4进入队列并让nlast等于节点4,节点3出队列并打印节点3,让节点3的孩子进入队列,节点5进入队列并让nlast等于节点5,节点6进入队列并让nlast等于节点6,此时发现last与上次出队列的节点3相等,于是换行,并将nlast赋给last(等于节点6),接下来类此。
1 void leveltraversal3(BinTree *T) 2 { 3 if(T == NULL) 4 return; 5 queues; 6 s.push(T); 7 BinTree *pcur,*last,*nlast; 8 last = T; 9 nlast = NULL; 10 while (!s.empty()) 11 { 12 pcur = s.front(); 13 cout << pcur->data; 14 s.pop(); 15 if (pcur->left) 16 { 17 s.push(pcur->left); 18 nlast = pcur->left; 19 } 20 if (pcur->right) 21 { 22 s.push(pcur->right); 23 nlast = pcur->right; 24 } 25 if (last == pcur) 26 { 27 cout << endl; 28 last = nlast; 29 } 30 } 31 }