樹是一個由n個有限節點組成並具有層次關係的集合,是一種非線性的數據結構。樹是由跟節點和它的子樹構成,所以樹的定義是遞歸的。二叉樹是樹的一種,它的特點是至多有兩顆字樹,並且二叉樹的子樹也有左右之分,不能互相顛倒。
二叉樹常用的遍歷方式有三種,即:前序遍歷,中序遍歷,後序遍歷,這三遍歷方式的主要卻別是訪問根結點和遍歷左子樹、右子樹的先後關係不一樣。
訪問順序:
前序遍歷:根->左->右
中序遍歷:左->根->右
後序遍歷:左->右->根
下面由樹的遞歸建立和對樹進行遞歸遍歷:樹的實現藉助鏈表,而鏈表的節點正是樹的結點,包含着一二數據域,指針域中包括分別指向左孩子和右孩子的指針
//定義節點
typedef struct Node { int data; struct Node* rchild; struct Node* lchild; }Node;
//遞歸建立樹
//建樹 Node* create_tree() { int _data; scanf("%d",&_data); if(_data==-1) { return NULL; } Node* root=(Node*)malloc(1*sizeof(Node)); root->data=_data; root->lchild=create_tree(); root->rchild=create_tree(); return root; }
//前序遍歷: 根->左->右
//遞歸前序遍歷 void qian_print(Node* root) { if(root!=NULL) { printf("%d\t",root->data); qian_print(root->lchild); qian_print(root->rchild); } }
中序遍歷:左->根->右
//遞歸中序遍歷 void zhong_print(Node* root) { if(root!=NULL) { zhong_print(root->lchild); printf("%d\t",root->data); zhong_print(root->rchild); } }
後序遍歷:左->右->根
//遞歸後序遍歷 void hou_print(Node* root) { if(root!=NULL) { hou_print(root->lchild); hou_print(root->rchild); printf("%d\t",root->data); } }
最後實現三個小練習
1.求葉子的節點數(左子樹爲空,右子樹也爲空)
void count_leaf(Node* root,int* count) { if(root!=NULL) { if(root->lchild==NULL && root->rchild==NULL) { (*count)++; } count_leaf(root->lchild,count); count_leaf(root->rchild,count); } }
2.求樹的深度
int deth(Node* root) { int dethval=0,dethl=0,dethr=0; if(root==NULL) { return 0; } dethl=deth(root->lchild); dethr=deth(root->rchild); dethval=1+(dethl>dethr?dethl:dethr); return dethval; } 3.copy二叉樹 Node* copy_tree(Node* root) { Node* newnode,*newrptr,*newlptr; if(root==NULL) { return NULL; } if(root->lchild!=NULL) { newlptr=copy_tree(root->lchild); } else { newlptr=NULL; } if(root->rchild!=NULL) { newrptr=copy_tree(root->rchild); } else { newrptr=NULL; } newnode=(Node*)malloc(1*sizeof(Node)); newnode->lchild=newlptr; newnode->rchild=newrptr; newnode->data=root->data; return newnode; }