数据结构实验(五)二叉树
6-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;
}
}
6-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;
}
6-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 ;
}
6-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 );
}
7-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;
}
7-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;
}