a.简介:树是由结点及连结结点的边组成。有根树的节点之间有父子关系。
2.二叉树:
a.简介:如果一颗树有1个根结点及所有结点的子结点数都不超过2,那么此树被称为有根二叉树。
b.二叉树可以递归地进行定义。
c.代码:二叉树的表达
// // Created by 叶子 on 2018/2/2. // 有根树的表达 // #include "iostream" using namespace std; struct Node { int p ,l,r;}; const int NIL= -1; Node T[100005],D[100005]; int n; void print (int u){ int i,c; cout << "node" << u << ":"; cout << "parent = " << T[u].p << ","; cout << "depth = "<<D[u].p<<","; if ( T[u].p == NIL) cout << "root,"; else if ( T[u].l == NIL) cout << "leaf,"; else cout << "internal ndoe,"; cout << "["; for ( i = 0 , c = T[u].l ; c != NIL; i++,c = T[c].r){ if (i) cout << "," ; cout <<c; } cout << "]" <<endl; } int rec(int u,int p){ D[u].p = p; if ( T[u].r != NIL ) rec(T[u].r,p); //? 这一句不是很理解 if ( T[u].l != NIL ) rec(T[u].l,p+1); } int main(){ int i,j,d,v,c,l,r; cin >> n; for ( i = 0 ; i < n ; i ++) T[i].p = T[i].l = T[i].r = NIL; for ( i = 0 ; i < n ; i ++){ cin >> v>> d; for ( j = 0 ; j < d ; j ++){ cin >> c; if ( j == 0 ) T[v].l = c; else T[l].r = c; l = c; T[c].p = v; } } for ( i = 0 ; i < n ; i ++){ if (T[i].p == NIL ) r = i ; } rec(r,0); for ( i = 0 ; i < n ; i ++) print(i); return 0 ; }
2.普通二叉树:
a.表达:
// // Created by 叶子 on 2018/2/2. // 二叉树的表达 // #include "cstdio" const int MAX = 10000; const int NIL = -1; struct Node{ int parent,left,right;}; Node T[MAX]; int n,D[MAX],H[MAX]; void setDepth(int u,int d){ if ( u == NIL) return; D[u] = d; setDepth(T[u].left,d+1); setDepth(T[u].right,d+1); } int setHeight(int u){ int h1 = 0 ,h2 = 0; if (T[u].left != NIL){ h1 = setHeight(T[u].left ) + 1; } if ( T[u].right != NIL){ h2 = setHeight(T[u].right) + 1; } return H[u] = ( h1 > h2 ? h1 : h2); } int getSibling(int u){ if (T[u].parent == NIL) return NIL; if ( T[T[u].parent].left != u && T[T[u].parent].left != NIL) return T[T[u].parent].left; if ( T[T[u].parent].right != u && T[T[u].parent].right != NIL) return T[T[u].parent].right; return NIL; } void print(int u){ printf("node %d:",u); printf("parent = %d,",T[u].parent); printf("sibling = %d,",getSibling(u)); int deg = 0; if (T[u].left != NIL) deg ++; if (T[u].right != NIL) deg ++; printf ("degree = %d,",deg); printf ("depth = %d,",D[u]); printf ("height = %d,",H[u]); if ( T[u].parent == NIL){ printf("root\n"); }else if ( T[u].left == NIL && T[u].right == NIL ){ printf("left\n"); }else{ printf("internal node\n"); } } int main(){ int v,l,r,root = 0 ; scanf("%d",&n); for ( int i = 0 ; i < n ; i ++ ) T[i].parent = NIL; for ( int i = 0 ; i < n ; i ++){ scanf("%d %d %d",&v,&l,&r); T[v].left = l; T[v].right = r; if ( l != NIL) T[l].parent = v; if ( r != NIL) T[r].right = v; } for ( int i = 0 ; i < n ; i ++) if ( T[i].parent == NIL) root = i; setDepth(root,0); setHeight(root); for ( int i = 0 ; i < n ; i ++) print(i); return 0; }
3.树的遍历:
a.三种遍历方式
前序遍历:根 左 右
中序遍历:左 根 右
后序遍历:左 右 根
是以根的位置定的顺序
b.注意的点:当用递归实现遍历算法时,如果树的结点数量大并且分布不均,很可能导致递归深度过深
c.代码:
// // Created by 叶子 on 2018/2/4. // 二叉树的遍历 // #include "stdio.h" const int MAX = 10000; const int NIL = -1; struct Node { int p,l,r;}; struct Node T[MAX]; int n; //前序遍历 void preParse(int u){ if ( u == NIL) return; printf(" %d",u); preParse(T[u].l); preParse(T[u].r); } //中序遍历 void inParse(int u){ if ( u== NIL) return; inParse(T[u].l); printf(" %d",u); inParse(T[u].r); } //后序遍历 void postParse(int u){ if ( u == NIL) return; postParse(T[u].l); postParse(T[u].r); printf(" %d",u); } int main(){ int i,v,l,r,root; scanf("%d",&n); for ( i = 0 ; i < n ; i ++){ T[i].p == NIL; } for ( i = 0 ; i < n ; i ++){ scanf("%d %d %d",&v,&l,&r); T[v].l = l; T[v].r = r; if ( l != NIL) T[l].p = v; if ( r != NIL) T[r].p = v; } for ( i = 0 ; i < n ; i ++) if ( T[i].p == NIL) root = i; printf("Precorder\n"); preParse(root); printf("\n"); printf("Inorder\n"); inParse(root); printf("\n"); printf("Postorder\n"); postParse(root); printf("\n"); return 0; }4.树的重建:
a.题目:根据树的先序遍历和中序遍历的结果,生成此树按后序遍历得到的结果
b.分析:可以在遍历先序遍历结果的同时,依次根据中序遍历得到树的左右子树
c.代码:
// // Created by 叶子 on 2018/2/4. // 根据树的先序遍历和中序遍历的结果得到后序遍历的结果 // #include "iostream" #include "vector" using namespace std; int n,pos; vector<int> pre,in,post; void rec(int l ,int r){ if ( l >= r) return; int root = pre[pos++]; int m = distance(in.begin(),find(in.begin(),in.end(),root)); rec(l,m); rec(m+1,r); post.push_back(root); } void solve(){ pos = 0; rec(0,pre.size()); for ( int i = 0 ; i < n ; i ++){ if ( i ) cout << " "; cout << post[i]; } cout << endl; } int main(){ int k; cin >> n; for ( int i = 0 ; i < n ; i ++){ cin >> k ; pre.push_back(k); } for ( int i = 0 ; i < n ; i++){ cin >> k; in.push_back(k); } solve(); return 0; }