求二叉樹的前中後序遞迴、迭代,樹的葉子節點,高度(c語言)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
#define MAX 100
typedef struct node* tree_pointer;
typedef struct node{
char data;
tree_pointer left_child,right_child;
}BiTree;
void CreateBiTree(BiTree **root);
void PreOrder(BiTree *root);
void InOrder(BiTree *root);
void PostOrder(BiTree *root);
void OPreOrder(BiTree *root);
void OInOrder(BiTree *root);
void OPostOrder(BiTree *root);
BiTree *STACK[MAX];
void push(int *top,BiTree *ptr);
BiTree *pop(int *top);
BiTree *Top(int top);
void treeshape(BiTree *root,int n);
int leaf(BiTree *root);
void treeheight(BiTree *root,int h);
int depth = 0;
int main()
{
BiTree *root;//這裡是一個指標,才能不把地址固定,進而可以進行malloc操作
printf("請根據先序輸入資料\n");
CreateBiTree(&root);//只有二重指標才可以改值
putchar('\n');
while(1)
{
printf("1、先序遍歷 2、中序便利 3、後序遍歷\n \
4、先序遞迴 5、中序遞迴 6、後序遞迴\n \
7、列印樹狀 8、列印葉子節點數 9、列印樹高度\n" );
printf("輸入-1退出\n");
int num;
scanf(" %d",&num);
if(num == -1)
break;
switch(num)
{
case 1:
PreOrder(root);
putchar('\n');
break;
case 2:InOrder(root);
putchar('\n');
break;
case 3:PostOrder(root);
putchar('\n');
break;
case 4:
memset(STACK,0,sizeof(STACK));
OPreOrder(root);
putchar('\n');
break;
case 5:memset(STACK,0,sizeof(STACK));
OInOrder(root);
putchar('\n');
break;
case 6:memset(STACK,0,sizeof(STACK));
OPostOrder(root);
putchar('\n');
break;
case 7:
treeshape(root,1);
putchar('\n');
break;
case 8:
printf("\n葉子結點為:%d\n",leaf(root));
break;
case 9:
treeheight(root,0);
printf("樹的高度為 %d\n",depth);
}
}
return 0;
}
void CreateBiTree(BiTree **root)
{
char ch;
scanf(" %c",&ch);
if(ch == '#')
*root = NULL;
else
{
*root = (BiTree*)malloc(sizeof(BiTree));
(*root)->data = ch;
CreateBiTree(&((*root)->left_child));
CreateBiTree(&((*root)->right_child));
}
}
void PreOrder(BiTree *root)
{
if(root)
{
printf("%c ",root->data);
PreOrder(root->left_child);
PreOrder(root->right_child);
}
}
void InOrder(BiTree *root)
{
if(root)
{
InOrder(root->left_child);
printf("%c ",root->data);
InOrder(root->right_child);
}
}
void PostOrder(BiTree *root)
{
if(root)
{
PostOrder(root->left_child);
PostOrder(root->right_child);
printf("%c ",root->data);
}
}
void push(int *top,BiTree *ptr)
{
if(*top == MAX-1)
{
printf("stack full\n");
return;
}
else
STACK[++(*top)] = ptr;//因為從-1,所以下一個元素0開始,所以先++
//0 開始,後++
}
BiTree *pop(int *top)
{
if(*top == -1)
{
printf("stack empty\n");
return NULL;
}
else
{
return STACK[(*top)--];//-1開始 從本元素減,所以後--;
//0開始,前--
}
}
void OPreOrder(BiTree *root)
{
int top = -1;//從個元素加起
BiTree *p = root;
while(p!=NULL || top!=-1)
{
while(p!=NULL)
{
printf("%c ",p->data);
push(&top,p);
p = p->left_child;
}
if(top!=-1)
{
p = pop(&top);
p = p->right_child;
}
}
}
void OInOrder(BiTree *root)
{
int top = -1;//從0個元素加起
BiTree *p = root;
while(p!=NULL || top!=-1)
{
while(p!=NULL)
{
push(&top,p);
p = p->left_child;
}
if(top!=-1)
{
p = pop(&top);
printf("%c ",p->data);
p = p->right_child;
}
}
}
void OPostOrder(BiTree *root)
{
int top = -1;//從0個元素加起
BiTree *p = root;
BiTree *q = NULL;
while(p!=NULL || top!=-1)
{
while(p!=NULL)//先遍歷左邊
{
push(&top,p);
p = p->left_child;
}
if(top!=-1)
{
p = Top(top);//獲得棧頂元素
if((p->right_child == NULL) || p->right_child == q)//如果右邊為空,或者右邊訪問過,就輸出
//切記,不能寫判斷左邊和右邊為空,如果那樣寫,就會進入死迴圈,永遠不能輸出
{
p = pop(&top);
printf("%c ",p->data);
q = p;//記下上一步做過的點
p =NULL;//將當前點設為空,就可以跳過開頭while迴圈
}
else
{
p = p->right_child;
}
}
}
}
BiTree *Top(int top)
{
return STACK[top];
}
void treeshape(BiTree *root,int n)//獲得樹的形狀
{
if (root == NULL)
return ;
treeshape(root->right_child,n+1);
for(int i=0;i<n;i++)
printf(" ");
printf("%c\n",root->data);
treeshape(root->left_child,n+1);
}
int leaf(BiTree *root)//獲得葉子節點個數
{
int left,right;
if(root == NULL)
return 0;
if(root->left_child == NULL && root->right_child == NULL)
return 1;
left = leaf(root->left_child);
right = leaf(root->right_child);
return left + right;
}
void treeheight(BiTree *root,int h)//獲得樹的高度,放在全域性變數depth裡面
{
if(root)
{
if(h > depth)
depth =h;
treeheight(root->left_child,h+1);
treeheight(root->right_child,h+1);
}
}
相關推薦
求二叉樹的前中後序遞迴、迭代,樹的葉子節點,高度(c語言)
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<assert.h> #define MAX 100 typedef struct n
前中後序遞迴遍歷樹的體會 with Python
前序:跟->左->右 中序:左->根->右 後序:左>右->根 採用遞迴遍歷時,編譯器/直譯器負責將遞迴函式呼叫過程壓入棧並保護現場,在不同位置處理根節點即可實現不同順序的遍歷。 import Tree def preOrderTraversa
Python學習中遞迴、迭代、生成器、函數語言程式設計的思考
遞迴函式 遞迴函式需要注意防止棧溢位。在計算機中,函式呼叫是通過棧(stack)這種資料結構實現的,每當進入一個函式呼叫,棧就會加一層棧幀,每當函式返回,棧就會減一層棧幀。由於棧的大小不是無限的,所以,遞迴呼叫的次數過多,會導致棧溢位。 解決遞迴呼叫棧溢位的方法是通過尾遞
二叉樹基礎操作 ,前中後序遍歷,求二叉樹高度,二叉搜尋樹(二叉排序樹)Java實現 程式碼集合
首先,定義一個樹類Tree.java public class Tree { public TreeNode root; } 定義樹節點類TreeNode.java public class TreeNode { public TreeNode(int
二叉樹的前中後序遍歷(遞迴和非遞迴版本)
各位讀者週末愉快呀,今天我想來說說一道很常見的面試題目 —— 關於二叉樹前中後序遍歷的實現。本文將以遞迴和非遞迴方式實現這 3 種遍歷方式,程式碼都比較短,可以放心食用。 先簡單說明一下這 3 種遍歷方式有什麼不同 —— 對於每種遍歷,樹中每個結點都需要經過 3 次(對於葉結點,其左右子樹視為空子樹),但前
二叉樹的前中後序遍歷(遞迴+非遞迴)
/** * 二叉樹節點類 * @author wj * */ class TreeNode{ int value; TreeNode left_Node; TreeNode right_Node; public TreeNode(int value) { this.value
二叉樹前序中序後序遞迴非遞迴解法
遞迴解法很簡單,構建一個輔助函式helper,改變一下其中的兩行程式碼的順序便可實現前序中序後序遍歷,程式碼如下: 前序遍歷(遞迴) vector<int> preorderTraversal(TreeNode* root) { vector<in
二叉樹的前中後序遍歷(遞迴&非遞迴)
中序遞迴: class Solution { public: vector<int> res; vector<int> inorderTraversal(Tre
javascript生成二叉樹, 以及其前中後序遍歷
序言 最近看了些面試題, 發現大多數都會問一個問題就是JavaScript生成二叉樹, 本來想偷懶百度看看算了, 可是發現好多網站部落格的程式碼都是一樣的, 並且生成的還是平衡二叉樹………. 如果我不輸入數字你給我生成一個試試. so, 看起來只能自己搞一下了. 百度百科–平衡二
二叉樹的前中後序遍歷(遞迴&非遞迴)
中序遞迴: class Solution { public: vector<int> res; vector<int> inorderTraversal(TreeNode * root) { inorder(root);
二叉樹的建立及前中後序遍歷和層次遍歷
樹是N個結點的有限集合,N=0時稱為空樹,任意一顆非空樹滿足以下條件: 有且只有一個特定的稱為根的結點 當N>1時,其他結點可分為m個互不相交的悠閒集合,其中每個集合本身又是一個棵樹,並稱為根節點的子樹 樹的定義是遞迴的,是一種遞迴的資料結構,樹作為一
二叉樹前序、中序、後序遞迴與非遞迴遍歷+層序遍歷(java)
前序遞迴遍歷演算法:訪問根結點-->遞迴遍歷根結點的左子樹-->遞迴遍歷根結點的右子樹 中序遞迴遍歷演算法:遞迴遍歷根結點的左子樹-->訪問根結點-->遞迴遍歷根結點的右子樹 後序遞迴遍歷演算法:遞迴遍歷根結
二叉樹先序後序遞迴建立,前中後序層次非遞迴遍歷,以及統計葉子結點個數以及樹的深度
下面的程式碼實現了二叉樹的先序或者後序遞迴建立,然後實現了二叉樹的非遞迴的先序中序後序遍歷,還有層次遍歷,以及統計樹的葉子結點個數和樹的深度。其中非遞迴的先中後序遍歷用到了鏈棧,層次遍歷用到了佇列。 程式設計平臺為Visual Studio 2012,語言為C,但不是純C,
二叉樹的建立及其前中後序遍歷
1 //二叉樹儲存結構: 2 struct node 3 { 4 Int data; 5 node *lchild; 6 node *rchild; 7 }; 8 9 //二叉樹在建樹前根節點不存在: 10 Node *root = NULL; 11 12
javascript實現二叉樹排序,前中後序遍歷,最大最小值特定值查詢以及刪除節點
函式執行時,會產生一個棧用來存放資料,當遍歷到目的節點時,操作結束以後,就會自動執行出棧操作,所以每次執行完畢指標都會自動跳回根節點。可以在開發者模式裡打斷點看到全過程。 <!DOCTYPE html> <html> <head> <me
二叉樹遍歷LeetCode#144 #94 #145 (前中後序遍歷)
題目:二叉樹的前序遍歷(遞迴以及非遞迴方法) 難度:Medium 思路:遞迴很簡單,非遞迴需要藉助棧來實現 程式碼: 遞迴程式碼 /** * Definition for a binary
前,中,後序遍歷二叉樹 (遞迴 && 非遞迴的棧 && 非遞迴非棧的線索二叉樹)
先簡單介紹下線索二叉樹,線索二叉樹不需要額外的空間便可以O(n)遍歷二叉樹,它充分利用了節點的空指標,若當前結點的左孩子不為空則其左指標指向左孩子結點,否則指向當前節點的前驅;若當前結點的右孩子不為空則其右指標指向右孩子結點,否則指向當前節點的後繼。具體看程式碼實現 前序遍
Leetcode:二叉樹的層序遍歷、前中後序遍歷非遞迴版
102. 二叉樹的層次遍歷 給定一個二叉樹,返回其按層次遍歷的節點值。 (即逐層地,從左到右訪問所有節點)。 例如: 給定二叉樹: [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回
二叉樹的前中後序遍歷
本文介紹二叉樹的前序,中序和後序遍歷,採用遞迴和非遞迴兩種方式實現。除此之外,還介紹了對二叉樹按層遍歷的方法。對樹的前中後序遍歷是深度優先搜尋的策略,因此用棧實現。對樹的按層遍歷是廣度優先搜尋,因此採用佇列實現。 樹的前序,中序和後序遍歷,都是針對父節點而言的。 二叉樹的定
非遞迴實現二叉樹遍歷(前/中/後序)
//基本資料結構 template<class T> struct BinaryTreeNode { T _data; BinaryTreeNode<T>* _left;