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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

二叉树(C++):创建,前中后序遍历(递归+非递归),获取叶子节点个数,获取树的高度

發布時間:2023/11/27 生活经验 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉树(C++):创建,前中后序遍历(递归+非递归),获取叶子节点个数,获取树的高度 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

        • 前言
        • 創建二叉樹
        • 先序遍歷
        • 中序遍歷
        • 后序遍歷
        • 獲取葉子節點個數
        • 獲取樹的高度
        • 測試代碼

前言

現有如下二叉樹:

關于二叉樹的相關操作,我們能夠發現二叉樹從根節點到子節點,以及每個中間節點基本都能夠拆分為若干個子節點的操作,且每個子節點的操作都和其頭節點操作一致。
所以我們針對二叉樹的操作都可以使用分治算+回溯/歸并算法進行

完整測試代碼見文末


創建二叉樹

二叉樹數據結構:

typedef struct tree
{char data;struct tree *left;struct tree *right;
}Tree,*TreeNode;

我們使用先序方式,創建如上二叉樹:
輸入如下: ABD***CE**FG***
創建過程

/*創建二叉樹*/
void createTree(TreeNode *root) {char val = 0;cin >> val; //持續輸入,直到完成一個二叉樹的構建if (val == '*') {//輸入為*則代表當前節點為空(*root) = NULL;} else {(*root) = (Tree *)malloc(sizeof(tree));if ((*root) == NULL) {cout << "create node failed " << endl;exit(-1);} else {(*root)->data = val;//為輸入的節點賦值createTree(&(*root)->left);//分治左孩子節點createTree(&(*root)->right);//分治右孩子節點}}
}

先序遍歷

先序遍歷二叉樹指:先遍歷二叉樹的根節點,再遍歷當前根節點所有左子樹,再遍歷當前根節點所有右子樹

因為這個過程針對子節點的遍歷和根節點是沒有任何區別的,所以可以使用分治進行處理

/*遞歸先序遍歷*/
void preOrder(Tree *root) {if (root == NULL) {return;}cout << root->data;preOrder(root->left);preOrder(root->right);
}

同樣可以使用棧進行非遞歸的先序遍歷,即
棧可以保存遍歷過程中的左節點,因為先序遍歷是先訪問根節點,其次就是左節點

while(p) {cout << p ->data; //訪問根節點s.push(p); //保存左子節點p = p->left;
}

接著再彈棧,直到獲取一個右節點

while(!s.empty()) {p = s.top();s.pop();p = p -> right;
}

接著再重復對右節點進行同樣的訪問操作,具體過程如下

/*非遞歸先序遍歷*/
void preOrderNoRecur(Tree *root) {if (root == NULL) {return;}stack<TreeNode> s;Tree *p = root;while(!s.empty() || p) {while(p) {cout << p ->data;s.push(p);p = p->left;}while(!s.empty()) {p = s.top();s.pop();p = p -> right;}}cout << endl;
}

中序遍歷

中序遍歷二叉樹是指:先訪問左節點,中間訪問根節點,最后訪問右節點
分治過程如下:

void inorder(Tree *root) {if (root == NULL) {return;}inorder(root -> left);cout << root -> data;inorder(root -> right);
}

中序遍歷二叉樹的非遞歸方式和先序類似,支持訪問的時機是在先訪問第一輪所有的左節點,再獲取右節點之前進行根節點的訪問,實現過程如下:

/*非遞歸中序遍歷*/
void inorderNoRecur(Tree *root) {if (root == NULL) {return;}stack<TreeNode> s;Tree *p = root;while(!s.empty() || p) {while(p) {s.push(p);p = p ->left;}while(!s.empty()) {p = s.top();cout << p->data;s.pop();p = p->right;}}cout << endl;
}

后序遍歷

后序遍歷二叉樹是指:先訪問左節點,再訪問右節點,最后訪問根節點
分治過程如下:

/*遞歸后序遍歷*/
void lastorder(Tree *root) {if (root == NULL) {return;}lastorder(root -> left);lastorder(root -> right);cout << root -> data;
}

非遞歸的訪問過程和先序/中序遍歷有差異,因為后序遍歷需要優先訪問完左節點、右節點
所以根節點的訪問前提是:

  1. 右子節點為空
  2. 右子節點已經訪問過

所以實現的過程中需要保存已經訪問過的右子節點

void lastorderNoRecur(Tree *root) {if (root == NULL) {return;}stack<TreeNode> s;Tree *p = root;Tree *lastvisit = NULL;//保存已經訪問過的右子節點/*先獲取到左子節點*/while(p) {s.push(p);p = p ->left;}while(!s.empty()) {p = s.top();s.pop();/*右節點已經為空或者已經訪問過,那么認為右節點已經訪問完,可以訪問根節點了*/if (p -> right == NULL || p ->right == lastvisit) {cout << p->data;lastvisit = p;} else {//否則,將右節點以及右節點的子節點入棧從而繼續訪問s.push(p);p = p -> right;/*每獲取到一個非空右節點,就將該右節點的左節點放入棧中*/while(p) {s.push(p);p = p -> left;}}}cout << endl;
}

獲取葉子節點個數

葉子節點的條件就是:左右子樹都為空
此時返回值應該為1
分治+歸并獲取葉子節點的個數

int getLeavesNode(Tree *root) {if (root == NULL) {return 0;} else {if (root -> left == NULL && root ->right == NULL) {return 1;}return getLeavesNode(root -> left) + getLeavesNode(root -> right);}
}

獲取樹的高度

樹的高度為左右子節點的 層數較大的一個數值
實現過程如下:

int heightTree(Tree *root) {int height = 0;if (root == NULL) {return 0;} else {int l_height = heightTree(root -> left);int r_height = heightTree(root -> right);height = l_height > r_height? l_height +1 :r_height+1;}return height;
}

測試代碼

#include <iostream>
#include <stack>
#include <vector>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>using namespace std;typedef struct tree
{char data;struct tree *left;struct tree *right;
}Tree,*TreeNode;/*創建二叉樹*/
void createTree(TreeNode *root) {char val = 0;cin >> val;if (val == '*') {(*root) = NULL;} else {(*root) = (Tree *)malloc(sizeof(tree));if ((*root) == NULL) {cout << "create node failed " << endl;exit(-1);} else {(*root)->data = val;createTree(&(*root)->left);createTree(&(*root)->right);}}
}/*遞歸先序遍歷*/
void preOrder(Tree *root) {if (root == NULL) {return;}cout << root->data;preOrder(root->left);preOrder(root->right);
}/*非遞歸先序遍歷*/
void preOrderNoRecur(Tree *root) {if (root == NULL) {return;}stack<TreeNode> s;Tree *p = root;while(!s.empty() || p) {while(p) {cout << p ->data;s.push(p);p = p->left;}while(!s.empty()) {p = s.top();s.pop();p = p -> right;}}cout << endl;}/*遞歸中序遍歷*/
void inorder(Tree *root) {if (root == NULL) {return;}inorder(root -> left);cout << root -> data;inorder(root -> right);
}/*非遞歸中序遍歷*/
void inorderNoRecur(Tree *root) {if (root == NULL) {return;}stack<TreeNode> s;Tree *p = root;while(!s.empty() || p) {while(p) {s.push(p);p = p ->left;}while(!s.empty()) {p = s.top();cout << p->data;s.pop();p = p->right;}}cout << endl;
}/*遞歸后序遍歷*/
void lastorder(Tree *root) {if (root == NULL) {return;}lastorder(root -> left);lastorder(root -> right);cout << root -> data;
}void lastorderNoRecur(Tree *root) {if (root == NULL) {return;}stack<TreeNode> s;Tree *p = root;Tree *lastvisit = NULL;while(p) {s.push(p);p = p ->left;}while(!s.empty()) {p = s.top();s.pop();/*右節點已經為空或者已經訪問過,那么認為右節點已經訪問完,可以訪問根節點了*/if (p -> right == NULL || p ->right == lastvisit) {cout << p->data;lastvisit = p;} else {//否則,將右節點以及右節點的子節點入棧從而繼續訪問s.push(p);p = p -> right;while(p) {s.push(p);p = p -> left;}}}cout << endl;
}int getLeavesNode(Tree *root) {if (root == NULL) {return 0;} else {if (root -> left == NULL && root ->right == NULL) {return 1;}return getLeavesNode(root -> left) + getLeavesNode(root -> right);}
}int heightTree(Tree *root) {int height = 0;if (root == NULL) {return 0;} else {int l_height = heightTree(root -> left);int r_height = heightTree(root -> right);height = l_height > r_height? l_height +1 :r_height+1;}return height;
}int main(int argc, char const *argv[])
{/* code */TreeNode root;cout << "construct the tree " << endl;createTree(&root);cout << "previous order recursion " << endl;preOrder(root);cout << "\nprevious order no recursion " << endl;preOrderNoRecur(root);cout << "inorder recursion " << endl;inorder(root);cout << "\ninorder no recursion " << endl;inorderNoRecur(root);cout << "lastorder recursion " << endl;lastorder(root);cout << "\nlastorder no recursion " << endl;lastorderNoRecur(root);cout << "height of the tree is " << heightTree(root) << endl;cout << "num leaves of the tree is " << getLeavesNode(root) << endl;return 0;
}

輸出如下:

#輸入
construct the tree 
ABD***CE**FG***
#輸出
previous order recursion 
ABDCEFG
previous order no recursion 
ABDCEFG
inorder recursion 
DBAECGF
inorder no recursion 
DBAECGF
lastorder recursion 
DBEGFCA
lastorder no recursion 
DBEGFCA
height of the tree is 4
num leaves of the tree is 3

總結

以上是生活随笔為你收集整理的二叉树(C++):创建,前中后序遍历(递归+非递归),获取叶子节点个数,获取树的高度的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。