二叉樹的創建與三種遍歷方式
作爲鹹魚,這個學期學習了一種極爲重要的數據結構:
二叉樹
和之前的線性數據結構比起來,二叉樹是非線性的,擁有多樣的創建和遍歷方式;
剛剛上手的時候,總會覺得有點暈頭轉向;
加之遞歸函數又有些生疏,剛開始學習的時候總是會出現一些莫名其妙的報錯;
之後筆者在通過自己編寫程序以及OJ刷題之後,漸漸,咳咳,自認爲掌握了二叉樹的基礎操作,現在將二叉樹的一些知識點整理下來:
那麼先從基礎的開始:
二叉樹的創建與三種遍歷方式
首先是定義二叉樹節點
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
};
接下來是最基礎的操作,二叉樹的創建:
遞歸創建,要注意節點的空間申請
struct TreeNode* buildTree(struct TreeNode* root)
{
int val;
scanf("%d", &val);
if(val == 0) {
root = nullptr; //指向空節點
return nullptr;
}
root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
root->val = val;
root->left = buildTree(root->left); //創建左子樹
root->right = buildTree(root->right); //創建右子樹
return root;
}
接下來是二叉樹的三種遍歷方式,
雖然先根,中根,後根遍歷的結果在順序上差別相當大;
但其實仔細分析遍歷過程的話,這三種的遞歸遍歷的思路非常接近;
而在代碼上也僅僅只有微妙的差異:
先根遍歷:
void scanTreePre(struct TreeNode *root)
{
if(!root) return;
printf("%d ", root->val);
scanTreePre(root->left);
scanTreePre(root->right);
}
中根遍歷:
void scanTreeMid(struct TreeNode *root)
{
if(!root) return;
scanTreeMid(root->left);
printf("%d ", root->val);
scanTreeMid(root->right);
}
後根遍歷:
void scanTreePost(struct TreeNode *root)
{
if(!root) return;
scanTreePost(root->left);
scanTreePost(root->right);
printf("%d ", root->val);
}
代碼非常精簡,思路也很清晰,即使用紙筆也可以很快模擬出遍歷過程
以下是主函數:
int main()
{
struct TreeNode *root = NULL; //創建二叉樹根節點
root = buildTree(root);
printf("preorder is: ");
scanTreePre(root);
printf("\nmidorder is: ");
scanTreeMid(root);
printf("\npostorder is: ");
scanTreePost(root);
return 0;
}
最後附上程序的運行結果