数据结构实验(五)二叉树

1|06-1 二叉树的遍历


就是简单的遍历

void InorderTraversal( BinTree BT ){ if( BT == NULL ) return; if( BT->Left != NULL ) InorderTraversal( BT->Left ); printf(" %c" , BT->Data); if( BT->Right != NULL ) InorderTraversal( BT->Right ); } void PreorderTraversal( BinTree BT ){ if( BT == NULL ) return; printf(" %c" , BT->Data); if( BT->Left != NULL ) PreorderTraversal( BT->Left ); if( BT->Right != NULL ) PreorderTraversal( BT->Right ); } void PostorderTraversal( BinTree BT ){ if( BT == NULL ) return; if( BT->Left != NULL ) PostorderTraversal( BT->Left ); if( BT->Right != NULL ) PostorderTraversal( BT->Right ); printf(" %c" , BT->Data); } void LevelorderTraversal( BinTree BT ){ if( BT == NULL ) return; BinTree q[100005] , u; int front = 1 , end = 1; q[front] = BT; while( front <= end ){ u = q[front++]; printf(" %c" , u->Data); if( u->Left != NULL ) q[++end] = u->Left; if( u->Right != NULL ) q[++end] = u->Right; } }

2|06-2 二叉树求深度和叶子数


一个点的深度就是父亲的深度+1,一个节点的叶子数就是他所有子树的叶子数之和

int GetDepthOfBiTree( BiTree T ){ if( T == NULL ) return 0; if( T->lchild == NULL && T->rchild == NULL ) return 1; int ldep , rdep; if( T->lchild != NULL ) ldep = GetDepthOfBiTree( T->lchild ); else ldep = 0; if( T->rchild != NULL ) rdep = GetDepthOfBiTree( T->rchild ); else rdep = 0; if( ldep > rdep ) return ldep + 1; else return rdep + 1; } int LeafCount( BiTree T ){ if( T == NULL ) return 0; if( T->lchild == NULL && T->rchild == NULL ) return 1; int lLeaf = 0 , rLeaf = 0; if( T->lchild != NULL ) lLeaf = LeafCount( T->lchild ); if( T->rchild != NULL ) rLeaf = LeafCount( T->rchild ); return lLeaf + rLeaf; }

3|06-3 二叉树的非递归遍历


用栈模拟一下就好,很简单

void InorderTraversal( BinTree BT ){ if( BT == NULL ) return ; int vis[512]; memset( vis , 0 , sizeof(vis) ); Stack s = CreateStack(); Push( s , BT ); while( !IsEmpty (s) ){ BinTree t = Peek(s); if( t->Left != NULL && vis[t->Left->Data] == 0){ vis[t->Left->Data] = 1; Push( s , t->Left ); } else{ printf(" %c" , t->Data ); Pop(s); if( t->Right != NULL ){ Push( s , t->Right ); } } } return ; } void PreorderTraversal( BinTree BT ){ if( BT == NULL ) return ; Stack s = CreateStack(); Push( s , BT ); while( !IsEmpty( s ) ){ BinTree t = Pop( s ); printf(" %c" , t->Data ); if( t->Right != NULL ) Push( s , t->Right ); if( t->Left != NULL ) Push( s , t->Left ); } } void PostorderTraversal( BinTree BT ){ if( BT == NULL ) return ; int vis[512]; memset( vis , 0 , sizeof(vis) ); Stack s = CreateStack(); Push( s , BT ); while( !IsEmpty(s) ){ BinTree t = Peek(s); if( t->Left != NULL && vis[t->Left->Data] == 0 ){ vis[t->Left->Data] = 1; Push( s , t->Left ); } else if( t->Right != NULL && vis[t->Right->Data] == 0 ){ vis[t->Right->Data] = 1; Push( s , t->Right ); } else{ printf(" %c" , t->Data ); Pop(s); } } return ; }

4|06-4 哈夫曼树及哈夫曼编码


模板算法

void reverse(char *CH){ int n=strlen(CH); for ( int i=0 , j = n-1 ; i<n/2 ; i++ , j -- ) CH[i] ^= CH[j] ^= CH[i] ^= CH[j]; } void SelectTwoMin(int upbound, HuffmanTree HT, int &s1, int &s2){ int val1 = 0x7f7f7f7f , val2 = 0x7f7f7f7f; s1 = s2 = 0; for( int i = 1 ; i <= upbound ; i ++ ){ if( HT[i].parent == 0 ){ if( HT[i].weight < val1 ) s2 = s1 , s1 = i , val2 = val1 , val1 = HT[i].weight; else if( HT[i].weight < val2 ) s2 = i , val2 = HT[i].weight; } } } void dfs( int x , const int len , char s[] , HuffmanTree HT , HuffmanCode &HC ){ if( HT[x].lchild == 0 && HT[x].rchild == 0 ){ HC[x] = new char[len]; for( int i = 0 ; i < len ; i ++ ) HC[x][i] = s[i]; return ; } char t[len]; for( int i = 0 ; i < len ; i ++ ) t[i] = s[i]; t[len] = '0' , dfs( HT[x].lchild , len+1 , t , HT , HC ); t[len] = '1' , dfs( HT[x].rchild , len+1 , t , HT , HC ); } void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n){ HT = ( HuffmanTree ) malloc( (2*n+5) * sizeof(HTNode) ); for( int i = 1 ; i <= n ; i ++ ){ HT[i].weight = w[i-1] , HT[i].parent = HT[i].lchild = HT[i].rchild = 0; } for( int i = n+1 , s1 , s2 ; i <= 2*n-1 ; i ++ ){ SelectTwoMin( i-1 , HT , s1 , s2 ); HT[i].weight = HT[s1].weight + HT[s2].weight; HT[i].parent = 0 , HT[s1].parent = HT[s2].parent = i; HT[i].lchild = s1 , HT[i].rchild = s2; } HC = new char *[n+1]; dfs( 2*n-1 , 0 , "" , HT , HC ); }

5|07-1 完全二叉树的层序遍历


最简单的做法就是 bfs,但是记录深度也可以用 dfs

#include<bits/stdc++.h> using namespace std; const int N = 35; int a[N] , p[N] , n , t ; void dfs( int i ){ if( i > n ) return; p[i] = a[t] , t --; dfs( i * 2 + 1 ); dfs( i * 2 ); } int32_t main() { cin >> n; for( int i = 1 ; i <= n ; i ++ ) cin >> a[i]; t = n , dfs( 1 ); for( int i = 1 ; i <= n ; i ++ ) cout << p[i] << ( i != n ? " " : "\n" ); return 0; }

6|07-2 浪漫侧影


二叉树的还原?

#include<bits/stdc++.h> using namespace std; const int N = 35; int a[N] , p[N] , n ; vector<int> resL , resR; vector< vector<int> >res; struct Node{ int value; Node * left , * right; Node(): value(-1) , left(nullptr) , right(nullptr) {}; void build( vector<int> Ino , vector<int> Suf ){ value = Suf.back() , left = new Node() , right = new Node(); int t = 0; for( auto it : Ino ){ if( it == value ) break; else t ++; } auto lInoBegin = Ino.begin() , lInoEnd = Ino.begin() + t; auto lSufBegin = Suf.begin() , lSufEnd = Suf.begin() + t; auto rInoBegin = Ino.begin() + t + 1 , rInoEnd = Ino.end(); auto rSufBegin = Suf.begin() + t , rSufEnd = Suf.end() - 1; vector<int> lIno,lSuf,rIno,rSuf; lIno.assign( lInoBegin , lInoEnd ); lSuf.assign( lSufBegin , lSufEnd ); rIno.assign( rInoBegin , rInoEnd ); rSuf.assign( rSufBegin , rSufEnd ); if( !lIno.empty() ) left->build( lIno , lSuf ); if( !rIno.empty() ) right->build( rIno , rSuf ); } } *root; int read() { int x = 0, f = 1, ch = getchar(); while ((ch < '0' || ch > '9') && ch != '-') ch = getchar(); if (ch == '-') f = -1, ch = getchar(); while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar(); return x * f; } void dfs( Node * t , int dep ){ res[dep].push_back( t->value ); if( t->right->value != -1 ) dfs( t->right , dep + 1 ); if( t->left->value != -1 ) dfs( t->left , dep + 1 ); return; } int32_t main() { int n = read(); vector<int> Ino , Suf; res.resize(n); for( int i = 1 , x ; i <= n ; i ++ ) x = read() , Ino.push_back( x ); for( int i = 1 , x ; i <= n ; i ++ ) x = read() , Suf.push_back( x ); root = new Node(); root->build( Ino , Suf ); resL.push_back( root->value ); resR.push_back( root->value ); dfs( root , 0 ); cout << "R:"; for( auto it : res ){ if( it.empty() ) break; cout << " " << it.front(); } cout << "\nL:"; for( auto it : res ){ if( it.empty() ) break; cout << " " << it.back(); } cout << "\n"; return 0; }

__EOF__

本文作者PHarr
本文链接https://www.cnblogs.com/PHarr/p/16927840.html
关于博主:前OIer,SMUer
版权声明CC BY-NC 4.0
声援博主:如果这篇文章对您有帮助,不妨给我点个赞
posted @   PHarr  阅读(63)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示