二叉搜索树的操作集
BinTree Insert ( BinTree BST, ElementType X )
{
if ( BST== NULL )
{
BST= ( BinTree) malloc ( sizeof ( BinTree) ) ;
BST-> Data= X;
BST-> Left= NULL ;
BST-> Right= NULL ;
}
else
{
if ( X> BST-> Data)
BST-> Right= Insert ( BST-> Right, X) ;
else if ( X< BST-> Data)
BST-> Left= Insert ( BST-> Left, X) ;
}
return BST;
}
BinTree Delete ( BinTree BST, ElementType X )
{
if ( BST== NULL )
printf ( "Not Found\n" ) ;
else
{
if ( X> BST-> Data)
BST-> Right= Delete ( BST-> Right, X) ;
else if ( X< BST-> Data)
BST-> Left= Delete ( BST-> Left, X) ;
else
{
if ( BST-> Left&& BST-> Right)
{
Position tmp= FindMin ( BST-> Right) ;
BST-> Data= tmp-> Data;
BST-> Right= Delete ( BST-> Right, BST-> Data) ;
}
else
{
Position tmp= BST;
if ( BST-> Left)
BST= BST-> Left;
else
BST= BST-> Right;
free ( tmp) ;
}
}
}
return BST;
}
Position Find ( BinTree BST, ElementType X )
{
if ( BST)
{
if ( X== BST-> Data)
return BST;
else if ( X> BST-> Data)
return Find ( BST-> Right, X) ;
else
return Find ( BST-> Left, X) ;
}
return BST;
}
Position FindMin ( BinTree BST )
{
if ( BST)
{
while ( BST-> Left)
BST= BST-> Left;
}
return BST;
}
Position FindMax ( BinTree BST )
{
if ( BST)
{
while ( BST-> Right)
BST= BST-> Right;
}
return BST;
}
二叉搜索树中的最近公共祖先
int find ( Tree T, int x)
{
if ( ! T) return 0 ;
if ( x== T-> Key) return 1 ;
if ( x< T-> Key) return find ( T-> Left, x) ;
else return find ( T-> Right, x) ;
}
int LCA ( Tree T, int u, int v )
{
if ( ! T) return ERROR;
if ( ! find ( T, u) || ! find ( T, v) ) return ERROR;
int data= T-> Key;
if ( ( u> data&& v< data) || ( u< data&& v> data) ) return data;
if ( u== data|| v== data) return data;
if ( u> data) return LCA ( T-> Right, u, v) ;
else return LCA ( T-> Left, u, v) ;
}
统计二叉树叶子结点个数
int LeafCount ( BiTree T)
{
int count;
if ( T== NULL ) count= 0 ;
else if ( T-> lchild== NULL && T-> rchild== NULL ) count= 1 ;
else count= LeafCount ( T-> lchild) + LeafCount ( T-> rchild) ;
return count;
}
二叉树的三种遍历(先序、中序和后序)
void Preorder ( BiTree T)
{
if ( T)
{
printf ( " %c" , T-> data) ;
Preorder ( T-> lchild) ;
Preorder ( T-> rchild) ;
}
}
void Inorder ( BiTree T)
{
if ( T)
{
Inorder ( T-> lchild) ;
printf ( " %c" , T-> data) ;
Inorder ( T-> rchild) ;
}
}
void Postorder ( BiTree T)
{
if ( T)
{
Postorder ( T-> lchild) ;
Postorder ( T-> rchild) ;
printf ( " %c" , T-> data) ;
}
}
二叉树的非递归遍历
void InorderTraversal ( BinTree BT )
{
BinTree t= BT;
Stack s= CreateStack ( ) ;
while ( t|| ! IsEmpty ( s) )
{
while ( t)
{
Push ( s, t) ;
t= t-> Left;
}
if ( ! IsEmpty ( s) )
{
t= Pop ( s) ;
printf ( " %c" , t-> Data) ;
t= t-> Right;
}
}
}
void PreorderTraversal ( BinTree BT )
{
BinTree t= BT;
Stack s= CreateStack ( ) ;
while ( t|| ! IsEmpty ( s) )
{
while ( t)
{
Push ( s, t) ;
printf ( " %c" , t-> Data) ;
t= t-> Left;
}
if ( ! IsEmpty ( s) )
{
t= Pop ( s) ;
t= t-> Right;
}
}
}
void PostorderTraversal ( BinTree BT )
{
BinTree t= BT;
Stack s= CreateStack ( ) ;
while ( t|| ! IsEmpty ( s) )
{
while ( t)
{
Push ( s, t) ;
t-> flag= 1 ;
t= t-> Left;
}
if ( ! IsEmpty ( s) )
{
t= Pop ( s) ;
if ( t-> flag== 1 )
{
Push ( s, t) ;
t-> flag = 2 ;
t= t-> Right;
}
else
{
printf ( " %c" , t-> Data) ;
t= NULL ;
}
}
}
}
是否二叉搜索树
bool IsBST ( BinTree T )
{
if ( T)
{
if ( T-> Left)
{
if ( T-> Left-> Data> T-> Data) return false ;
if ( T-> Left-> Right)
if ( T-> Left-> Right-> Data> T-> Data) return false ;
else return IsBST ( T-> Left) ;
}
if ( T-> Right)
{
if ( T-> Right-> Data< T-> Data) return false ;
if ( T-> Right-> Left)
if ( T-> Right-> Left-> Data< T-> Data) return false ;
else return IsBST ( T-> Right) ;
}
}
return true ;
}
7-41 还原二叉树 (25分)
# include <iostream>
# include <cstdio>
using namespace std;
const int maxn= 1e5 + 10 ;
int n;
char a[ 110 ] , b[ 110 ] ;
struct node
{
int l;
int r;
} tree[ maxn] ;
int build ( int l1, int r1, int l2, int r2)
{
if ( l1> r1) return - 1 ;
int root= a[ l1] , pos= l2;
while ( b[ pos] != root) pos++ ;
int len= pos- l2;
tree[ root] . l= build ( l1+ 1 , l1+ len, l2, pos- 1 ) ;
tree[ root] . r= build ( l1+ len+ 1 , r1, pos+ 1 , r2) ;
return root;
}
int look ( int root)
{
if ( root== - 1 ) return 0 ;
else return max ( look ( tree[ root] . l) , look ( tree[ root] . r) ) + 1 ;
}
int main ( )
{
cin>> n;
for ( int i= 1 ; i<= n; i++ ) cin>> a[ i] ;
for ( int i= 1 ; i<= n; i++ ) cin>> b[ i] ;
build ( 1 , n, 1 , n) ;
cout<< look ( a[ 1 ] ) ;
return 0 ;
}
7-42 玩转二叉树 (25分)
# include <iostream>
# include <string>
# include <map>
# include <set>
# include <queue>
# include <cstdio>
# include <vector>
# include <cstring>
# include <algorithm>
# include <iomanip>
# include <cmath>
# include <fstream>
# define X first
# define Y second
# define INF 0x3f3f3f3f
# define pii pair< int , int >
using namespace std;
typedef long long ll;
typedef unsigned long long llu;
const int maxn= 1e5 + 10 ;
int n, a[ 110 ] , b[ 110 ] , ans[ 110 ] , cnt;
struct node
{
int l;
int r;
} tree[ 1010 ] ;
int build ( int l1, int r1, int l2, int r2)
{
if ( l1> r1) return - 1 ;
int root= b[ l2] , pos= l1;
while ( a[ pos] != root) pos++ ;
int len= pos- l1;
tree[ root] . l= build ( l1, pos- 1 , l2+ 1 , l2+ len) ;
tree[ root] . r= build ( pos+ 1 , r1, l2+ len+ 1 , r2) ;
return root;
}
void change ( int root)
{
if ( root== - 1 ) return ;
if ( tree[ root] . l== - 1 && tree[ root] . r== - 1 ) return ;
swap ( tree[ root] . l, tree[ root] . r) ;
change ( tree[ root] . l) ;
change ( tree[ root] . r) ;
}
void pint ( int root)
{
queue< int > q;
q. push ( root) ;
while ( q. size ( ) )
{
int cur= q. front ( ) ;
q. pop ( ) ;
ans[ cnt++ ] = cur;
if ( tree[ cur] . l!= - 1 ) q. push ( tree[ cur] . l) ;
if ( tree[ cur] . r!= - 1 ) q. push ( tree[ cur] . r) ;
}
for ( int i= 0 ; i< cnt; i++ )
{
if ( i== 0 ) printf ( "%d" , ans[ i] ) ;
else printf ( " %d" , ans[ i] ) ;
}
}
int main ( )
{
scanf ( "%d" , & n) ;
for ( int i= 1 ; i<= n; i++ ) scanf ( "%d" , & a[ i] ) ;
for ( int i= 1 ; i<= n; i++ ) scanf ( "%d" , & b[ i] ) ;
build ( 1 , n, 1 , n) ;
change ( b[ 1 ] ) ;
pint ( b[ 1 ] ) ;
return 0 ;
}
树的遍历(25分)
# include <iostream>
# include <string>
# include <map>
# include <set>
# include <queue>
# include <cstdio>
# include <vector>
# include <cstring>
# include <algorithm>
# include <iomanip>
# include <cmath>
# include <fstream>
# define X first
# define Y second
# define INF 0x3f3f3f3f
# define pii pair< int , int >
using namespace std;
typedef long long ll;
typedef unsigned long long llu;
const int maxn= 1e5 + 10 ;
int n, a[ 110 ] , b[ 110 ] , ans[ 110 ] , cnt;
struct node
{
int l;
int r;
} tree[ 1010 ] ;
int build ( int l1, int r1, int l2, int r2)
{
if ( l1> r1) return - 1 ;
int root= a[ r2] , pos= l1;
while ( b[ pos] != root) pos++ ;
int len= pos- l1;
tree[ root] . l= build ( l1, pos- 1 , l2, l2+ len- 1 ) ;
tree[ root] . r= build ( pos+ 1 , r1, l2+ len, r2- 1 ) ;
return root;
}
void pint ( int root)
{
queue< int > q;
q. push ( root) ;
while ( q. size ( ) )
{
int cur= q. front ( ) ;
q. pop ( ) ;
ans[ cnt++ ] = cur;
if ( tree[ cur] . l!= - 1 ) q. push ( tree[ cur] . l) ;
if ( tree[ cur] . r!= - 1 ) q. push ( tree[ cur] . r) ;
}
for ( int i= 0 ; i< cnt; i++ )
{
if ( i== 0 ) printf ( "%d" , ans[ i] ) ;
else printf ( " %d" , ans[ i] ) ;
}
}
int main ( )
{
scanf ( "%d" , & n) ;
for ( int i= 1 ; i<= n; i++ ) scanf ( "%d" , & a[ i] ) ;
for ( int i= 1 ; i<= n; i++ ) scanf ( "%d" , & b[ i] ) ;
build ( 1 , n, 1 , n) ;
pint ( a[ n] ) ;
return 0 ;
}
7-44 搜索树判断 (25分)
# include <iostream>
# include <cstdio>
# include <vector>
using namespace std;
const int maxn= 1e5 + 10 ;
int n, a[ 1010 ] ;
vector< int > v;
void getv ( int l, int r, int flag)
{
int root= a[ l] ;
int left= l+ 1 , right= r;
if ( ! flag)
{
while ( left<= r&& a[ left] < root) left++ ;
while ( right> l&& a[ right] >= root) right-- ;
}
else
{
while ( left<= r&& a[ left] >= root) left++ ;
while ( right> l&& a[ right] < root) right-- ;
}
if ( left- right!= 1 ) return ;
getv ( l+ 1 , right, flag) ;
getv ( left, r, flag) ;
v. push_back ( root) ;
}
int main ( )
{
cin>> n;
for ( int i= 1 ; i<= n; i++ ) cin>> a[ i] ;
getv ( 1 , n, 0 ) ;
if ( v. size ( ) != n)
{
v. clear ( ) ;
getv ( 1 , n, 1 ) ;
}
if ( v. size ( ) == n)
{
cout<< "YES" << endl;
for ( int i= 0 ; i< n; i++ )
{
if ( i== 0 ) cout<< v[ i] ;
else cout<< ' ' << v[ i] ;
}
}
else cout<< "NO" << endl;
return 0 ;
}
7-45 是否完全二叉搜索树 (30分)
# include <iostream>
# include <string>
# include <cstdio>
using namespace std;
typedef long long ll;
typedef unsigned long long llu;
const int maxn= 1e5 + 10 ;
int n, a[ 110 ] , flag, cnt, tree[ 1010 ] ;
void build ( int p, int pos)
{
if ( tree[ p] == 0 ) tree[ p] = a[ pos] ;
else
{
if ( a[ pos] > tree[ p] ) build ( p<< 1 , pos) ;
else build ( p<< 1 | 1 , pos) ;
}
return ;
}
int main ( )
{
scanf ( "%d" , & n) ;
for ( int i= 1 ; i<= n; i++ ) scanf ( "%d" , & a[ i] ) , build ( 1 , i) ;
for ( int i= 1 ; i< 1010 ; i++ )
{
if ( tree[ i] )
{
if ( flag) cout<< " " ;
else flag= 1 ;
cout<< tree[ i] ;
cnt= i;
}
}
if ( cnt> n) cout<< endl<< "NO" << endl;
else cout<< endl<< "YES" << endl;
return 0 ;
}