思考了一会,yy出了一个结论:
很显然,对于任意一颗子树中的所有节点来说,根节点必须是第一个插入的,根节点插入以后,这颗子树的其他所有节点会分成两拨,
大于根节点权值的和小于根节点权值的,这两部分不会互相影响,可以转化成新的两个更小的子树的构造过程。
而在构造过程中要想不破坏原来的bst的结构,就必须满足:
任意节点的插入不会比它的祖先更早,否则就会是一颗不一样的bst了。
若不理解请回忆bst的插入过程。
于是乎发现:要想满足这个规律只要做先根遍历即可,而要使字典序最小,只要先序遍历就是答案。
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 5 int n, cnt; 6 7 struct Node 8 { 9 Node * ch[2]; 10 int v; 11 bool cmp( int x ) 12 { 13 if ( x == v ) return -1; 14 return x < v ? 0 : 1; 15 } 16 }; 17 18 Node * root; 19 20 void insert( Node * & o, int x ) 21 { 22 if ( o == NULL ) 23 { 24 o = new Node (); 25 o->ch[0] = o->ch[1] = NULL; 26 o->v = x; 27 return ; 28 } 29 int d = o->cmp(x); 30 if ( d == -1 ) return ; 31 insert( o->ch[d], x ); 32 } 33 34 /* 35 Node * find( Node * o, int x ) 36 { 37 if ( o == NULL ) return NULL; 38 int d = o->cmp(x); 39 if ( d == -1 ) return o; 40 return find( o->ch[d], x ); 41 } 42 43 void remove( Node * & o, int x ) 44 { 45 if ( o == NULL ) return ; 46 int d = o->cmp(x); 47 if ( d == -1 ) 48 { 49 if ( o->ch[0] == NULL ) 50 { 51 Node * tmp = o; 52 o = o->ch[1]; 53 delete tmp; 54 } 55 else if ( o->ch[1] == NULL ) 56 { 57 Node * tmp = o; 58 o = o->ch[0]; 59 delete tmp; 60 } 61 else 62 { 63 Node * p = o, * q = o->ch[0]; 64 while ( q->ch[1] != NULL ) 65 { 66 p = q; 67 q = q->ch[1]; 68 } 69 o->v = q->v; 70 if ( p != o ) 71 { 72 p->ch[1] = q->ch[0]; 73 delete q; 74 } 75 else 76 { 77 p->ch[0] = q->ch[0]; 78 delete q; 79 } 80 } 81 } 82 else 83 { 84 remove( o->ch[d], x ); 85 } 86 } 87 */ 88 89 void free( Node * o ) 90 { 91 if ( o != NULL ) 92 { 93 free(o->ch[0]); 94 free(o->ch[1]); 95 delete o; 96 } 97 } 98 99 void visit( Node * o ) 100 { 101 cnt++; 102 printf("%d", o->v); 103 if ( cnt != n ) putchar(' '); 104 else putchar(' '); 105 } 106 107 void preorder( Node * o ) 108 { 109 if ( o ) 110 { 111 visit(o); 112 preorder(o->ch[0]); 113 preorder(o->ch[1]); 114 } 115 } 116 117 /* 118 void inorder( Node * o ) 119 { 120 if ( o ) 121 { 122 inorder(o->ch[0]); 123 visit(o); 124 inorder(o->ch[1]); 125 } 126 } 127 128 void postorder( Node * o ) 129 { 130 if ( o ) 131 { 132 postorder(o->ch[0]); 133 postorder(o->ch[1]); 134 visit(o); 135 } 136 } 137 */ 138 139 int main () 140 { 141 while ( scanf("%d", &n) != EOF ) 142 { 143 root = NULL; 144 cnt = 0; 145 for ( int i = 0; i < n; i++ ) 146 { 147 int tmp; 148 scanf("%d", &tmp); 149 insert( root, tmp ); 150 } 151 preorder(root); 152 free(root); 153 } 154 return 0; 155 }