平衡二叉树

  1 #include<time.h>

  2 #include<stdio.h>  

  3 #include<stdlib.h> 

  4 //左子树比右子树高一

  5 #define LH 1

  6 //左子树和右子树一样高

  7 #define EH 0

  8 //左子树比右子树低一

  9 #define RH -1

 10 #define EQ(a,b) ((a) == (b))

 11 #define LT(a,b) ((a) < (b))

 12 #define LQ(a,b)((a) <= (b))

 13 

 14 typedef struct BSTNode

 15 {

 16     int data;

 17     int bf;

 18     BSTNode * lchild;

 19     BSTNode * rchild;

 20 }BSTNode;

 21 typedef BSTNode * BSTree;

 22 

 23 //    左旋

 24 void leftRotate(BSTree & root) 

 25 {

 26     BSTree rc = root->rchild;

 27     root->rchild = rc->lchild;

 28     rc->lchild = root;

 29     root = rc;

 30 }

 31 //    右旋

 32 void rightRotate(BSTree & root) 

 33 {

 34     BSTree lc = root->lchild;

 35     root->lchild = lc->rchild;

 36     lc->rchild = root;

 37     root = lc;

 38 }

 39 //    对二叉树root进行左平衡处理(LL型和LR型)

 40 void leftBalance(BSTree & root) 

 41 {

 42     BSTree lc = root->lchild;

 43     switch (lc->bf) 

 44     {

 45         //LL型的只需要进行右旋操作

 46     case LH:

 47         //右旋之后根和左子树都的平衡的

 48         root->bf = EH;

 49         lc->bf = EH;

 50         //右旋操作

 51         rightRotate(root);

 52         break;

 53         //LR型的需要进行左旋操作,然后右旋操作

 54     case RH:

 55         BSTree rc = lc->rchild;

 56         switch (rc->bf) 

 57         {

 58         case LH:

 59             root->bf = RH;

 60             lc->bf = EH;

 61             break;

 62         case EH:

 63             root->bf = EH;

 64             lc->bf = EH;

 65             break;

 66         case RH:

 67             root->bf = EH;

 68             lc->bf = LH;

 69             break;

 70         }

 71         rc->bf = EH;

 72         leftRotate(root->lchild);

 73         rightRotate(root);

 74         break;

 75     }

 76 }

 77 //    功能:对二叉树root进行左平衡处理(RR型和RL型)

 78 void rightBalance(BSTree & root) 

 79 {

 80     BSTree rc = root->rchild;

 81     switch (rc->bf) 

 82     {

 83         //RR型只需要做左旋操作

 84     case RH:

 85         root->bf = EH;

 86         rc->bf = EH;

 87         //左旋操作

 88         leftRotate(root);

 89         break;

 90         //RL型需要先做右旋操作,然后做左旋操作

 91     case LH:

 92         BSTree lc = rc->lchild;

 93         switch (lc->bf) 

 94         {

 95         case LH:

 96             root->bf = EH;

 97             rc->bf = RH;

 98             break;

 99         case EH:

100             root->bf = EH;

101             rc->bf = EH;

102             break;

103         case RH:

104             root->bf = LH;

105             rc->bf = EH;

106             break;

107         }

108         lc->bf = EH;

109         rightRotate(root->rchild);

110         leftRotate(root);

111         break;

112     }

113 }

114 //    功能:把元素data插入平衡二叉树root中

115 bool insert(BSTree & root, int data, bool & taller) 

116 {

117     if (NULL == root) 

118     {

119         root = (BSTree)malloc(sizeof(BSTNode));

120         root->rchild = NULL;

121         root->lchild = NULL;

122         root->data = data;

123         root->bf = EH;

124         taller = true;

125     }

126     else

127     {

128         //该元素已经在平衡二叉树中存在了

129         if (data == root->data) 

130         {

131             taller = false;

132             return false;

133         }

134         //插入左子树

135         else if (data < root->data) 

136         {

137             if (!insert(root->lchild, data, taller)) 

138             {

139                 return false;

140             }

141             //插入成功,并且树变高了

142             if (taller) 

143             {

144                 switch (root->bf) 

145                 {

146                 case LH:

147                     leftBalance(root);

148                     //平衡二叉树做完左平衡操作后

149                     //树高没有变化,故taller = false

150                     taller = false;

151                     break;

152                 case EH:

153                     root->bf = LH;

154                     //原来是平衡的故插入一个元素后

155                     //树高必然变高

156                     taller = true;

157                     break;

158                 case RH:

159                     root->bf = EH;

160                     //原来是右子树比左子树高,但是当向左子树中

161                     //插入一个元素的时候,树变平衡了,故taller = false

162                     taller = false;

163                     break;

164                 default:

165                     break;

166                 }

167             }

168         }

169         //插入右子树

170         else 

171         {

172             if (!insert(root->rchild, data, taller)) 

173             {

174                 return 0;

175             }

176             if (taller) 

177             {

178                 switch (root->bf) 

179                 {

180                 case LH:

181                     root->bf = EH;

182                     taller = false;

183                     break;

184                 case EH:

185                     root->bf = RH;

186                     taller = true;

187                     break;

188                 case RH:

189                     rightBalance(root);

190                     taller = false;

191                     break;

192                 }

193             }

194         }

195     }

196     return true;

197 }

198 //   在平衡二叉树中查找int节点

199 int * search(BSTree & root, int data) 

200 {

201     if (root ==NULL) 

202     {

203         return NULL;

204     }

205     

206     if (root->data == data) 

207     {

208         return &root->data;

209     }

210     else if (data < root->data) 

211     {

212         return search(root->lchild, data);

213     } 

214     else 

215     {

216         return search(root->rchild, data);

217     }

218 }

219 //    功能:输出平衡二叉树中的所有的元素(小->大,中序遍历)

220 void print(BSTree & root)

221 {

222     if (NULL == root) 

223     {

224         return ;

225     }

226     

227     print(root->lchild);

228     printf("%d ",root->data);

229     print(root->rchild);

230 }

231 //    功能:释放平衡二叉树的空间

232 void clear(BSTree & root) 

233 {

234     if (NULL == root) 

235     {

236         return ;

237     }

238     clear(root->lchild);

239     clear(root->rchild);

240     free(root);

241 }

242 int DeleteAVL(BSTree &T, int key, bool &shorter){

243     if (!T)

244     {//No such key

245         shorter = false;

246         return 0;

247     }

248     else

249     {

250         if (EQ(key, T->data))    //找到了需要删除的结点

251         {

252             //如果该结点的lchild 和

253             //rchild 至少有一个为NULL

254             //则大功告成,否则请参照

255             //下方解释

256             BSTree q = T;

257             if (!T->lchild)//如果该结点的lchild 为NULL

258             {

259                 q = T;

260                 T = T->rchild;

261                 free(q);

262                 shorter = true;

263                 return 1;

264             }

265             else if (!T->rchild){//如果该结点的rchild 为 NULL

266                 q = T;

267                 T = T->lchild;//如果不是&(引用)的强大功能,这句话是没有意义的

268                 free(q);

269                 shorter = true;

270                 return 1;

271             }

272             else {

273                 //删除一个左右孩子都不为空的结点

274                 //使该结点的直接前驱p的data替换该结点的data

275                 //然后改变key=p.data

276                 BSTree s = T->lchild;

277                 while (s->rchild)

278                     s = s->rchild;

279                 T->data = s->data;

280                 key = s->data;//Now, delete the vertice whose data was the new key

281             }

282         }

283         if (LQ(key, T->data)){//这里与InsertAVL不同

284             if (!DeleteAVL(T->lchild, key, shorter)) return 0;

285             if (shorter){

286                 switch(T->bf){

287                 case LH:T->bf = EH; shorter = true;break;

288                 case EH:T->bf = RH;shorter = false;break;

289                 case RH:rightBalance(T); 

290                     if (T->rchild->bf == EH)

291                         shorter = false;

292                     else 

293                         shorter = true;break;

294                 }

295             }

296         }

297         else{

298             if (!DeleteAVL(T->rchild, key, shorter)) return 0;

299             if (shorter){

300                 switch(T->bf){

301                 case LH:leftBalance(T);

302                     if (T->lchild->bf == EH)

303                         shorter = false;

304                     else 

305                         shorter = true;break;

306                 case EH:T->bf = LH; shorter = false;break;

307                 case RH:T->bf = EH;shorter = true;break;

308                 }

309             }

310         }

311     }

312     return 1;

313 }//Delete

314 void menu()  

315 {  

316     printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙ ⊙☆⊙    主菜单     ⊙☆⊙ ⊙☆⊙ ⊙☆⊙ ⊙☆⊙\n");  

317     printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙请按№ 1:连续插入数据 输入0结束插入⊙☆⊙ ⊙☆⊙ ⊙☆⊙\n");  

318     printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙请按№ 2:查找数据                  ⊙☆⊙ ⊙☆⊙ ⊙☆⊙\n");  

319     printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙请按№ 3删除特定数据               ⊙☆⊙ ⊙☆⊙ ⊙☆⊙\n");  

320     printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙请按№ 4输出当前结果                   ⊙☆⊙ ⊙☆⊙ ⊙☆⊙\n"); 

321     printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙请按№ 5结束程序                   ⊙☆⊙ ⊙☆⊙ ⊙☆⊙\n");

322 }  

323 int main()

324 {

325     BSTree root = NULL;

326     int num,n;

327     bool taller = false,shorter;

328     system("color 2e");  

329     menu();

330     while(1)  

331     {  

332         scanf("%d",&num); 

333         //if(num==5) break;

334         switch (num)  

335         {  

336         case 1:

337             system("cls");

338             printf("请插入数据 ,输入0结束插入\n");

339             while(scanf("%d",&n))

340             {

341                 if(n==0) break;

342                 else insert(root,n,taller);

343             }

344             system("cls");

345             menu();

346             break;

347         case 2: 

348             system("cls");

349             printf("请输入要查询的数\n");

350             scanf("%d",&n);

351             int *p;

352             p=search(root,n);

353             if (p==NULL) 

354             {

355                 printf("对不起 没有找到 %d!\n",n);

356             }

357             else 

358             {

359                 printf("恭喜你 数据中存在 %d!\n",n);

360             }

361             menu();

362             break;  

363         case 3: 

364             system("cls");

365             printf("请输入要删除的数据\n");

366             scanf("%d",&n);

367             DeleteAVL(root,n,shorter);

368             menu();

369             break;

370         case 4:

371             system("cls");

372             print(root); 

373             printf("输入0进入主菜单\n");

374             scanf("%d",&n);

375             if(!n)

376               menu();

377             break;

378         case 5:

379             clear(root);

380             return 0;        

381         }

382     }

383     return 0;

384 }

原文转自:http://blog.csdn.net/hnust_xiehonghao/article/details/7938869

你可能感兴趣的:(二叉树)