二叉樹的各種遍歷演算法C++實現
阿新 • • 發佈:2018-12-31
大概在網上摘抄和總結了二叉樹的幾種遍歷方法,有遞迴和非遞迴的,先貼在這裡,用的時候在來看看。再次謝謝網上的各種資源。謝謝CSDN博主SJF0115,謝謝劍指offer作者何海濤~
#include"stdafx.h" #include<iostream> #include<stack> #include<queue> using namespace std; //二叉樹結點 typedef struct BinaryTreeNode{ //資料 char data; //左右孩子指標 struct BinaryTreeNode *lchild, *rchild; }BinaryTreeNode, *BiTree; //按先序序列建立二叉樹 int CreateBiTree(BiTree &T){ char data; //按先序次序輸入二叉樹中結點的值(一個字元),‘#’表示空樹 scanf_s("%c", &data); if (data == '#'){ T = NULL; } else{ T = (BiTree)malloc(sizeof(BinaryTreeNode)); //生成根結點 T->data = data; //構造左子樹 CreateBiTree(T->lchild); //構造右子樹 CreateBiTree(T->rchild); } return 0; } //輸出 void Visit(BiTree T){ if (T->data != '#'){ printf("%c ", T->data); } } //先序遍歷 void PreOrder(BiTree T) { if (T != NULL){ //訪問根節點 Visit(T); //訪問左子結點 PreOrder(T->lchild); //訪問右子結點 PreOrder(T->rchild); } } //中序遍歷 void InOrder(BiTree T) { if (T != NULL){ //訪問左子結點 InOrder(T->lchild); //訪問根節點 Visit(T); //訪問右子結點 InOrder(T->rchild); } } //後序遍歷 void PostOrder(BiTree T) { if (T != NULL){ //訪問左子結點 PostOrder(T->lchild); //訪問右子結點 PostOrder(T->rchild); //訪問根節點 Visit(T); } } /* 先序遍歷(非遞迴) 思路:訪問T->data後,將T入棧,遍歷左子樹;遍歷完左子樹返回時,棧頂元素應為T,出棧,再先序遍歷T的右子樹。 */ void PreOrder2(BiTree T) { stack<BiTree> stack; //p是遍歷指標 BiTree p = T; //棧不空或者p不空時迴圈 while (p || !stack.empty()) { if (p != NULL) { //存入棧中 stack.push(p); //訪問根節點 printf("%c ", p->data); //遍歷左子樹 p = p->lchild; } else { //退棧 p = stack.top(); stack.pop(); //訪問右子樹 p = p->rchild; } }//while } /* 中序遍歷(非遞迴) 思路:T是要遍歷樹的根指標,中序遍歷要求在遍歷完左子樹後,訪問根,再遍歷右子樹。 先將T入棧,遍歷左子樹;遍歷完左子樹返回時,棧頂元素應為T,出棧,訪問T->data,再中序遍歷T的右子樹。 */ void InOrder2(BiTree T) { stack<BiTree> stack; //p是遍歷指標 BiTree p = T; //棧不空或者p不空時迴圈 while (p || !stack.empty()) { if (p != NULL){ //存入棧中 stack.push(p); //遍歷左子樹 p = p->lchild; } else { //退棧,訪問根節點 p = stack.top(); printf("%c ", p->data); stack.pop(); //訪問右子樹 p = p->rchild; } }//while } //後序遍歷(非遞迴) typedef struct BinaryTreeNodePost { BiTree biTree; char tag; }BinaryTreeNodePost, *BiTreePost; void PostOrder2(BiTree T) { stack<BiTreePost> stack; //p是遍歷指標 BiTree p = T; BiTreePost BT; //棧不空或者p不空時迴圈 while (p != NULL || !stack.empty()) { //遍歷左子樹 while (p != NULL) { BT = (BiTreePost)malloc(sizeof(BinaryTreeNodePost)); BT->biTree = p; //訪問過左子樹 BT->tag = 'L'; stack.push(BT); p = p->lchild; } //左右子樹訪問完畢訪問根節點 while (!stack.empty() && (stack.top())->tag == 'R') { BT = stack.top(); //退棧 stack.pop(); BT->biTree; printf("%c ", BT->biTree->data); } //遍歷右子樹 if (!stack.empty()) { BT = stack.top(); //訪問過右子樹 BT->tag = 'R'; p = BT->biTree; p = p->rchild; } }//while } //層次遍歷 void LevelOrder(BiTree T) { BiTree p = T; //佇列 queue<BiTree> queue; //根節點入隊 queue.push(p); //佇列不空迴圈 while (!queue.empty()) { //對頭元素出隊 p = queue.front(); //訪問p指向的結點 printf("%c ", p->data); //退出佇列 queue.pop(); //左子樹不空,將左子樹入隊 if (p->lchild != NULL) { queue.push(p->lchild); } //右子樹不空,將右子樹入隊 if (p->rchild != NULL) { queue.push(p->rchild); } } } /* @"之"字形或是"S"型層級遍歷; @方法是:注意每一層是怎麼遍歷的,順序如何,只要 @分析出規律就可以寫出程式碼了 */ void S_PrintBinaryTree(BinaryTreeNode *pRoot) { //if (pRoot) //return; std::stack<BinaryTreeNode* >levels[2]; //兩個棧用於兩個入棧順序; int current = 0; //狀態標識,當前狀態; int next = 1; //下一狀態; levels[current].push(pRoot); while (!levels[0].empty() || !levels[1].empty()) { BinaryTreeNode* pNode = levels[current].top(); levels[current].pop(); printf("%c ", pNode->data); if (current == 0) { if (pNode->rchild != NULL) levels[next].push(pNode->rchild); if (pNode->lchild != NULL) levels[next].push(pNode->lchild); } else { if (pNode->lchild != NULL) levels[next].push(pNode->lchild); if (pNode->rchild != NULL) levels[next].push(pNode->rchild); } if (levels[current].empty()) { printf("\n"); current = 1 - current; next = 1 - next; } } } int main() { BiTree T; CreateBiTree(T); printf("先序遍歷:\n"); PreOrder(T); printf("\n"); printf("先序遍歷(非遞迴):\n"); PreOrder2(T); printf("\n"); printf("中序遍歷:\n"); InOrder(T); printf("\n"); printf("中序遍歷(非遞迴):\n"); InOrder2(T); printf("\n"); printf("後序遍歷:\n"); PostOrder(T); printf("\n"); printf("後序遍歷(非遞迴):\n"); PostOrder2(T); printf("\n"); printf("層次遍歷:\n"); LevelOrder(T); printf("\n"); printf("S形層次遍歷:\n"); S_PrintBinaryTree(T); printf("\n"); return 0; }
測試用例:
輸入:
ABC##DE#G##F###
輸出:
測試用例:
輸入:
ABC##DE#G##F###
輸出: