日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二叉树的遍历:先序 中序 后序遍历的递归与非递归实现及层序遍历

發(fā)布時間:2024/2/28 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉树的遍历:先序 中序 后序遍历的递归与非递归实现及层序遍历 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

二叉樹的定義:一種基本的數(shù)據(jù)結構,是一種每個節(jié)點的兒子數(shù)目都不多于2的樹

樹節(jié)點的定義如下:

// 樹(節(jié)點)定義 struct TreeNode {int data; // 值TreeNode* left; // 左節(jié)點TreeNode* right;// 右節(jié)點 };

創(chuàng)建樹(從上而下構建,我們以0表空節(jié)點)

結果如下圖:

代碼如下:

// 按照前序建立二叉樹,這里我們建立下面的樹 // 8 // 6 11 // 4 7 12 // 所以輸入順序是:864007001101200 void createTree(TreeNode*& t) { cout<<"請輸入數(shù)據(jù):"<<endl;int val = 0;cin>>val;// 0表結束if (0 == val){t = NULL;}else {t = new TreeNode();t->data = val;cout<<"開始建立:"<<val<<"的左節(jié)點:";createTree(t->left);cout<<"開始建立:"<<val<<"右節(jié)點:";createTree(t->right);} }

前序遍歷的遞歸法和非遞歸法:

結果如下圖:

代碼如下:

前序遍歷 / // 遞歸法 void Pre_Recursive(TreeNode* pTree) { if (pTree != NULL){cout<<pTree->data<<endl; // 根節(jié)點Pre_Recursive(pTree->left); // 左子Pre_Recursive(pTree->right); // 右子} }// 非遞歸法 void Pre_No_Recursive(TreeNode* pTree) { TreeNode* pTemp = pTree;stack<TreeNode*> treeStack;while(pTemp || !treeStack.empty()){// pTemp有效時就訪問,入棧,指向左子,一直這樣while(pTemp != NULL){// 訪問cout<<pTemp->data<<endl;// 壓入treeStack.push(pTemp);// 指向左子pTemp = pTemp->left;}// 棧非空時,回退一個節(jié)點,指向右子if (pTemp == NULL && !treeStack.empty()){pTemp = treeStack.top();// 指向右子pTemp = pTemp->right;// 彈出treeStack.pop();}} }

中序遍歷的遞歸法和非遞歸法:

結果如下圖:

代碼如下:

中序遍歷 / // 遞歸法 void Mid_Recursive(TreeNode* pTree) { if (pTree != NULL){Mid_Recursive(pTree->left); // 左子cout<<pTree->data<<endl; // 根節(jié)點Mid_Recursive(pTree->right); // 右子} }// 非遞歸法 void Mid_No_Recursive(TreeNode* pTree) { TreeNode* pTemp = pTree;stack<TreeNode*> treeStack;while(pTemp || !treeStack.empty()){// pTemp有效時就入棧,指向左子,一直這樣while(pTemp != NULL){// 壓入treeStack.push(pTemp);// 指向左子pTemp = pTemp->left;}if (pTemp == NULL && !treeStack.empty()){pTemp = treeStack.top();cout<<pTemp->data<<endl;// 指向右子pTemp = pTemp->right;// 彈出treeStack.pop();}} }

后序遍歷的遞歸法和非遞歸法:

結果如下圖:

代碼如下:

后序遍歷 / // 遞歸法 void After_Recursive(TreeNode* pTree) { if (pTree != NULL){After_Recursive(pTree->left); // 左子After_Recursive(pTree->right); // 右子cout<<pTree->data<<endl; // 根節(jié)點} }// 非遞歸法 void After_No_Recursive(TreeNode* pTree) { TreeNode* pTemp = pTree;stack<TreeNode*> treeStack1;// 臨時存儲節(jié)點stack<TreeNode*> treeStack2;// 存儲所有的節(jié)點,順序:根節(jié)點,右子,左子,后面只需打印即可while(pTemp || !treeStack1.empty()){// pTemp有效時就入棧,指向左子,一直這樣while(pTemp != NULL){// 壓入本節(jié)點treeStack1.push(pTemp);treeStack2.push(pTemp);// 指向右子pTemp = pTemp->right;}if(pTemp == NULL && !treeStack1.empty()) {pTemp = treeStack1.top();pTemp = pTemp->left;treeStack1.pop();}}// 由于存儲順序是:根節(jié)點,右子,左子,這里只需逐個打印while(!treeStack2.empty()){pTemp = treeStack2.top();cout<<pTemp->data<<endl;treeStack2.pop();} }

層序遍歷的非遞歸法:

結果如下圖:

代碼如下:

// 層序遍歷 void Level_Recursive(TreeNode* pTree) {if (pTree == NULL){return;}queue<TreeNode*> que;que.push(pTree);while(!que.empty()){// 取得隊列頭部元素,后把節(jié)點出隊TreeNode* pTemp = que.front();que.pop();cout<<pTemp->data<<endl;// 壓入左子,右子if (pTemp->left != NULL){que.push(pTemp->left);}if (pTemp->right != NULL){que.push(pTemp->right);}} }

完整代碼如下:

#include <iostream> #include <stack> #include <queue> using namespace std;// 樹(節(jié)點)定義 struct TreeNode {int data;TreeNode* left;TreeNode* right; };// 按照前序建立二叉樹,這里我們建立下面的樹 // 8 // 6 11 // 4 7 12 // 所以輸入順序是:864007001101200 void createTree(TreeNode*& t) { cout<<"請輸入數(shù)據(jù):"<<endl;int val = 0;cin>>val;// 0表結束if (0 == val){t = NULL;}else {t = new TreeNode();t->data = val;cout<<"開始建立:"<<val<<"的左節(jié)點:";createTree(t->left);cout<<"開始建立:"<<val<<"右節(jié)點:";createTree(t->right);} }前序遍歷 / // 遞歸法 void Pre_Recursive(TreeNode* pTree) { if (pTree != NULL){cout<<pTree->data<<endl; // 根節(jié)點Pre_Recursive(pTree->left); // 左子Pre_Recursive(pTree->right); // 右子} }// 非遞歸法 void Pre_No_Recursive(TreeNode* pTree) { TreeNode* pTemp = pTree;stack<TreeNode*> treeStack;while(pTemp || !treeStack.empty()){// pTemp有效時就訪問,入棧,指向左子,一直這樣while(pTemp != NULL){// 訪問cout<<pTemp->data<<endl;// 壓入treeStack.push(pTemp);// 指向左子pTemp = pTemp->left;}// 棧非空時,回退一個節(jié)點,指向右子if (pTemp == NULL && !treeStack.empty()){pTemp = treeStack.top();// 指向右子pTemp = pTemp->right;// 彈出treeStack.pop();}} }中序遍歷 / // 遞歸法 void Mid_Recursive(TreeNode* pTree) { if (pTree != NULL){Mid_Recursive(pTree->left); // 左子cout<<pTree->data<<endl; // 根節(jié)點Mid_Recursive(pTree->right); // 右子} }// 非遞歸法 void Mid_No_Recursive(TreeNode* pTree) { TreeNode* pTemp = pTree;stack<TreeNode*> treeStack;while(pTemp || !treeStack.empty()){// pTemp有效時就入棧,指向左子,一直這樣while(pTemp != NULL){// 壓入treeStack.push(pTemp);// 指向左子pTemp = pTemp->left;}if (pTemp == NULL && !treeStack.empty()){pTemp = treeStack.top();cout<<pTemp->data<<endl;// 指向右子pTemp = pTemp->right;// 彈出treeStack.pop();}} }后序遍歷 / // 遞歸法 void After_Recursive(TreeNode* pTree) { if (pTree != NULL){After_Recursive(pTree->left); // 左子After_Recursive(pTree->right); // 右子cout<<pTree->data<<endl; // 根節(jié)點} }// 非遞歸法 void After_No_Recursive(TreeNode* pTree) { TreeNode* pTemp = pTree;stack<TreeNode*> treeStack1;// 臨時存儲節(jié)點stack<TreeNode*> treeStack2;// 存儲所有的節(jié)點,順序:根節(jié)點,右子,左子,后面只需打印即可while(pTemp || !treeStack1.empty()){// pTemp有效時就入棧,指向左子,一直這樣while(pTemp != NULL){// 壓入本節(jié)點treeStack1.push(pTemp);treeStack2.push(pTemp);// 指向右子pTemp = pTemp->right;}if(pTemp == NULL && !treeStack1.empty()) {pTemp = treeStack1.top();pTemp = pTemp->left;treeStack1.pop();}}// 由于存儲順序是:根節(jié)點,右子,左子,這里只需逐個打印while(!treeStack2.empty()){pTemp = treeStack2.top();cout<<pTemp->data<<endl;treeStack2.pop();} }// 層序遍歷 void Level_Recursive(TreeNode* pTree) {if (pTree == NULL){return;}queue<TreeNode*> que;que.push(pTree);while(!que.empty()){// 取得隊列頭部元素,后把節(jié)點出隊TreeNode* pTemp = que.front();que.pop();cout<<pTemp->data<<endl;// 壓入左子,右子if (pTemp->left != NULL){que.push(pTemp->left);}if (pTemp->right != NULL){que.push(pTemp->right);}} }int main() {TreeNode* pTree = NULL;createTree(pTree);// 前序-遞歸法cout<<"\n遞歸法前序遍歷樹"<<endl;Pre_Recursive(pTree);// 前序-非遞歸法cout<<"\n非遞歸法前序遍歷樹"<<endl;Pre_No_Recursive(pTree);// 中序-遞歸法cout<<"\n遞歸法中序遍歷樹"<<endl;Mid_Recursive(pTree);// 中序-非遞歸法cout<<"\n非遞歸法中序遍歷樹"<<endl;Mid_No_Recursive(pTree);// 后序-遞歸法cout<<"\n遞歸法后序遍歷樹"<<endl;After_Recursive(pTree);// 后序-非遞歸法cout<<"\n非遞歸法后序遍歷樹"<<endl;After_No_Recursive(pTree);// 層序遍歷-非遞歸法cout<<"\n非遞歸法層序遍歷樹"<<endl;Level_Recursive(pTree);system("pause"); }

?

總結

以上是生活随笔為你收集整理的二叉树的遍历:先序 中序 后序遍历的递归与非递归实现及层序遍历的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。