二叉树总结一
二叉樹的知識點1:
二叉樹存儲結構
前序建立二叉樹
前序遍歷、中序遍歷、后序遍歷(遞歸、非遞歸)
二叉樹節點總數
二叉樹葉子節點數
二叉樹深度
遍歷二叉樹第i層節點
分層遍歷二叉樹(遞歸、非遞歸)
求二叉樹中節點的最大距離
已知前序、中序,重建二叉樹:
?
以下為具體程序,在devc++中驗證正確:?
/*
abd##e##c##
前序:a b d e c
中序:d b e a c
后序:d e b c a
*/
?
#include<stdio.h>
#include<stdlib.h>
#include<stack>
#include<vector>
?
using namespace std;
?
struct node{
?????? char value;
?????? struct node * left;
?????? struct node * right;
};
?
typedef struct node Node;
?
int max_dis=0;
?
//建樹
Node* create_tree(){
???? Node * root = NULL;
???? char input;
???? scanf("%c",&input);
???? if(input == '#'){
????????? return NULL;??????????????
???? }else{
????????? root = (Node *)malloc(sizeof(Node));
????????? if(NULL == root){
????????????????? printf("memory allocation wrong");
????????????????? return NULL;
????????? }
????????? root->value = input;
????????? root->left = create_tree();
????????? root->right = create_tree();
???? }
???? return root;
}
?
//遞歸前序遍歷
void qianxu_travel(Node * root){
???? if(NULL == root){
???????????? return;
???? }
???? printf("%c ",root->value);
???? qianxu_travel(root->left);
???? qianxu_travel(root->right);
}
?
//遞歸中序遍歷
void zhongxu_travel(Node * root){
???? if(NULL == root){
???????????? return;
???? }
???? zhongxu_travel(root->left);
???? printf("%c ",root->value);
???? zhongxu_travel(root->right);
}
?
//遞歸后序遍歷
void houxu_travel(Node * root){
???? if(NULL == root){
???????????? return;
???? }
???? houxu_travel(root->left);
???? houxu_travel(root->right);
???? printf("%c ",root->value);???????????
}
?
//前序遍歷非遞歸
void qianxu_no_rec(Node* root){
???? stack<Node*> s;
???? while(NULL != root || !s.empty()){
???????? if(NULL != root){
???????????? printf("%c ",root->value);
???????????? s.push(root);
???????????? root = root->left;
???????? }else{
???????????? root = s.top();
???????????? s.pop();
???????????? root = root->right;
???????? }????????
???? }
}
?
//中序遍歷非遞歸
void zhongxu_norec(Node* root){
???? stack<Node*> s;
???? while(NULL !=root || !s.empty()){
????????? if(NULL != root){
?????????????? s.push(root);
?????????????? root = root->left;
????????? }else{
?????????????? root = s.top();
?????????????? s.pop();
?????????????? printf("%c ",root->value);
?????????????? root = root->right;
????????? }???????????????????
???? }??
}
?
//遞歸遍歷第i層節點
int level_i_travle(Node* root, int level){
???? if(NULL == root || level < 0){
???????????? return 0;
???? }?
???? if(level == 1){
????????????? printf("%c ",root->value);
???? }
???? return level_i_travle(root->left,level-1)+level_i_travle(root->right,level-1);
}
?
//非遞歸分層遍歷二叉樹
void level_norec(Node* root){
???? if(NULL == root){
???????????? return;
???? }
???? vector<Node*> v;
???? v.push_back(root);
???? int cur = 0, last = 0;
???? while(cur < v.size()){?? //使用游標,不出隊列
?????????? last = v.size();
?????????? while(cur < last){
???????????????????? printf("%c ",v[cur]->value);
???????????????????? if(v[cur]->left){
??????????????????????????? v.push_back(v[cur]->left);
???????????????????? }
???????????????????? if(v[cur]->right){
??????????????????????????? v.push_back(v[cur]->right);
???????????????????? }
???????????????????? cur ++;
?????????? }??????
?????????? printf("\n");
???? }
}
?
//求葉子節點的個數
int leaf_num(Node* root){
??? if(NULL == root){
??????????? return 0;
??? }
??? if(NULL == root->left && NULL == root->right){
??????????? return 1;
??? }
??? return leaf_num(root->left) + leaf_num(root->right);
}
?
//求二叉樹的節點個數
int node_num(Node* root){
??? if(NULL == root){
??????????? return 0;
??? }
??? return 1+node_num(root->left)+node_num(root->right);??
}
?
//求二叉樹的高度
int height(Node* root){
??? if(NULL == root){
??????????? return 0;
??? }
??? int num1 =? height(root->left);
??? int num2 =? height(root->right);
??? if(num1 >= num2){
??????????? return 1+num1;
??? }else{
????????? return 1+num2;
??? }
}
?
//求二叉樹中節點的最大距離
int max_distance(Node* root){
??? if(NULL == root){
??????????? return 0;
??? }
??? int num1 = max_distance(root->left);
??? int num2 = max_distance(root->right);
??? if(max_dis < (1+num1+num2)){
?????????? max_dis = 1+num1+num2;
??? }
??? if(num1 >= num2){
??????????? return 1+num1;
??? }else{
????????? return 1+num2;
??? }
}
?
//根據前序、中序,重建二叉樹
void rebuild(char* preOrder, char* inOrder, int treeLen, Node** root){
???? //邊界判斷
???? if(NULL == preOrder || NULL == inOrder){
???????????? return;
???? }
???? Node* p = (Node*)malloc(sizeof(Node));? //根節點賦值
???? p->value = preOrder[0];
???? p->left = NULL;
???? p->right = NULL;
?
???? if(NULL == *root){
???????????? *root = p;
???? }
????
???? if(treeLen == 1){??? //剪枝
??????????????? return;
???? }
????
???? int left_len = 0;
???? int right_len = 0;
???? int tmp_len = 0;
???? char* left_inOrder = inOrder;? //求左子樹的長度
???? while(*left_inOrder != *preOrder){
????????? if(NULL == left_inOrder || NULL == preOrder){
????????????????? return;
????????? }?????????
????????? tmp_len ++;
????????? if(tmp_len > treeLen){
????????????????? break;
????????? }
????????? left_inOrder++;
???? }
?
???? left_len = left_inOrder - inOrder;
???? right_len = treeLen - 1 - left_len;
????
???? if(left_len > 0){
???????????????? rebuild(preOrder+1,inOrder,left_len,&((*root)->left));? //遞歸建造左子樹
???? }
?
???? if(treeLen-left_len+1 > 0){
????????????????? rebuild(preOrder+left_len+1,inOrder+left_len+1,right_len,&((*root)->right));? //遞歸建造右子樹
???? }
}
??
int main(){
???
??? Node * root = NULL;
??? char* szPreOrder = "abdcef";
??? char* szInOrder = "dbaecf";
????
??? //傳指針的指針,用于后續打印
?? /* rebuild1(szPreOrder, szInOrder, 6, &root);
???
??? printf("前序遞歸遍歷序列:\n");
??? qianxu_travel(root);
??? printf("\n");
?? */
???
??? printf("輸入以建立二叉樹:\n");
??? root = create_tree();
???
??? printf("非遞歸分層遍歷二叉樹:\n");
??? level_norec(root);
???
??? int k = 3;
??? printf("第%d層節點:\n",k);
??? level_i_travle(root,k);
??? printf("\n");
???
??? printf("葉子節點個數:%d\n",leaf_num(root));
???
??? printf("節點個數:%d\n",node_num(root));
???
??? printf("高度:%d\n",height(root));
???
??? printf("前序遞歸遍歷序列:\n");
??? qianxu_travel(root);
??? printf("\n");
???
??? printf("前序非遞歸遍歷序列:\n");
??? qianxu_no_rec(root);
??? printf("\n");
???
??? printf("中序遍歷序列:\n");
??? zhongxu_travel(root);
??? printf("\n");
???
??? printf("中序非遞歸遍歷序列:\n");
??? zhongxu_norec(root);
??? printf("\n");
???
??? printf("后序遍歷序列:\n");
??? houxu_travel(root);
??? printf("\n");
???
??? printf("后序非遞歸遍歷序列:\n");
?? // houxu_norec(root);
???
??? printf("節點之間的最大距離:\n");
??? max_distance(root);
??? printf("%d\n",max_dis);
???
??? destory_tree(root);
???
??? system("pause");
??? return main();
}
總結
- 上一篇: ARM CPU雄起!x86被越甩越远
- 下一篇: 十六进制除法运算法则_苏教版数学七年级上