Advertisement
Guest User

Untitled

a guest
Jul 6th, 2015
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 32.27 KB | None | 0 0
  1. /*******************************************************************************
  2.  
  3. Algoritmos de manipulação de uma arvore binária de pesquisa ordenada por ordem
  4. crescente. Os nos da arvore são compactos e armazenam elementos inteiros.
  5.  
  6. Autor : António Manuel Adrego da Rocha Data : Abril de 2015
  7.  
  8. Algorithms for manipulating a binary search tree sorted by increasing order. The
  9. tree nodes are compact and store integer elements.
  10.  
  11. *******************************************************************************/
  12.  
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15. #include "abp.h"
  16. #include "stack.h"
  17. #include "queue.h"
  18.  
  19. struct abpnode /* estrutura do no compacto - compact node data structure */
  20. {
  21. PtABPNode PtLeft; /* ponteiro para o no esquerdo da arvore - left node pointer */
  22. PtABPNode PtRight; /* ponteiro para o no direito da arvore - right node pointer */
  23. int Elem; /* elemento inteiro armazenado na ABP - integer element stored in the BST */
  24. };
  25.  
  26. /*********************** Controlo Centralizado de Erro ************************/
  27.  
  28. static unsigned int Error = OK; /* inicialização do erro */
  29.  
  30. static char *ErrorMsg[] = { "sem erro - without error", "abp inexistente - bst does not exist", "sem memoria - out of memory",
  31. "ponteiro nulo - null pointer", "arvore vazia - empty tree", "elemento existente - element already exists",
  32. "elemento inexistente - element does not exist", "ficheiro inexistente - file does not exist" };
  33.  
  34. static char *AbnormalErrorMsg = "erro desconhecido - unknown error";
  35.  
  36. /******* N representa o número de mensagens de erro previstas no módulo *******/
  37.  
  38. #define N (sizeof (ErrorMsg) / sizeof (char *))
  39.  
  40. /************************ Alusão às Funções Auxiliares ************************/
  41.  
  42. static PtABPNode ABPNodeCreate (int);
  43. static void ABPNodeDestroy (PtABPNode *);
  44. static PtABPNode SearchRec (PtABPNode, int);
  45. static PtABPNode SearchRep (PtABPNode, int);
  46. static PtABPNode KMinRec (PtABPNode, unsigned int);
  47. static void NodeDelete (PtABPNode *);
  48. static int FindMin (PtABPNode);
  49. static void ListInOrder (PtABPNode, int [], unsigned int *);
  50. static void Balance (PtABPNode *, int [], int , int);
  51. static void Display (PtABPNode, unsigned int);
  52. static void StoreFilePreOrder (PtABPNode, FILE *);
  53. static PtABPNode CopyRec (PtABPNode);
  54.  
  55. /*************************** Definição das Funções ****************************/
  56.  
  57. int ABPErrorCode (void)
  58. {
  59. return Error;
  60. }
  61.  
  62. /******************************************************************************/
  63.  
  64. char *ABPErrorMessage (void)
  65. {
  66. if (Error < N) return ErrorMsg[Error];
  67. else return AbnormalErrorMsg; /* não há mensagem de erro - no error message */
  68. }
  69.  
  70. /******************************************************************************/
  71.  
  72. PtABPNode ABPCreate (void)
  73. {
  74. return NULL;
  75. }
  76.  
  77. /******************************************************************************/
  78.  
  79. void ABPDestroy (PtABPNode *proot)
  80. {
  81. if (*proot != NULL)
  82. {
  83. ABPDestroy (&(*proot)->PtLeft); /* destruir a subarvore esquerda - destroying the left subtree */
  84. ABPDestroy (&(*proot)->PtRight); /* destruir a subarvore direita - destroying the right subtree */
  85. ABPNodeDestroy (proot); /* eliminar o elemento - releasing the element */
  86. }
  87. }
  88.  
  89. /******************************************************************************/
  90.  
  91. unsigned int ABPSize (PtABPNode proot) /* cálculo do número de elementos recursiva - recursive number of nodes */
  92. {
  93. if (proot == NULL) { Error = ABP_EMPTY; return 0; } /* arvore vazia - empty tree */
  94. else
  95. {
  96. Error = OK;
  97. return 1 + ABPSize (proot->PtLeft) + ABPSize (proot->PtRight);
  98. }
  99. }
  100.  
  101. /******************************************************************************/
  102.  
  103. unsigned int ABPHeight (PtABPNode proot)
  104. {
  105. unsigned int LeftHeight, RightHeight;
  106.  
  107. if (proot == NULL) { Error = ABP_EMPTY; return 0; } /* no externo no nível 0 - external node is level 0*/
  108. else
  109. {
  110. Error = OK;
  111. LeftHeight = ABPHeight (proot->PtLeft); /* subarvore esquerda - left subtree */
  112. RightHeight = ABPHeight (proot->PtRight); /* subarvore direita - right subtree */
  113.  
  114. if (LeftHeight > RightHeight) return LeftHeight + 1;
  115. else return RightHeight + 1;
  116. }
  117. }
  118.  
  119. /******************************************************************************/
  120.  
  121. int ABPSearch (PtABPNode proot, int pelem)
  122. {
  123. if (proot == NULL) { Error = ABP_EMPTY; return 0; }
  124.  
  125. if (SearchRec (proot, pelem) == NULL) { Error = NO_ELEM; return 0; }
  126. else { Error = OK; return 1; }
  127. }
  128.  
  129. /******************************************************************************/
  130.  
  131. PtABPNode ABPMinRec (PtABPNode proot) /* pesquisa de mínimo recursiva - recursive minimum search */
  132. {
  133. Error = OK;
  134. if (proot == NULL) { Error = ABP_EMPTY; return NULL; }
  135. else if (proot->PtLeft == NULL) return proot;
  136. else return ABPMinRec (proot->PtLeft);
  137. }
  138.  
  139. /******************************************************************************/
  140.  
  141. PtABPNode ABPMaxRec (PtABPNode proot) /* pesquisa de máximo recursiva - recursive maximum search */
  142. {
  143. Error = OK;
  144. if (proot == NULL) { Error = ABP_EMPTY; return NULL; }
  145. else if (proot->PtRight == NULL) return proot;
  146. else return ABPMaxRec (proot->PtRight);
  147. }
  148.  
  149. /******************************************************************************/
  150.  
  151. PtABPNode ABPMinRep (PtABPNode proot) /* pesquisa de mínimo repetitiva - repetitive minimum search */
  152. {
  153. if (proot == NULL) { Error = ABP_EMPTY; return NULL; }
  154.  
  155. Error = OK;
  156. while (proot->PtLeft != NULL) proot = proot->PtLeft;
  157. return proot;
  158. }
  159.  
  160. /******************************************************************************/
  161.  
  162. PtABPNode ABPKMin (PtABPNode proot, unsigned int pk)
  163. {
  164. if (proot == NULL) { Error = ABP_EMPTY; return NULL; }
  165. /* K inválido ou arvore com menos elementos do que K - invalid k or tree with less elemenst */
  166. if (pk < 1 || ABPSize (proot) < pk) { Error = NO_ELEM; return NULL; }
  167. else { Error = OK; return KMinRec (proot, pk); }
  168. }
  169.  
  170. /******************************************************************************/
  171.  
  172. void ABPInsertRec (PtABPNode *proot, int pelem) /* inserção recursiva - recursive insertion */
  173. {
  174. if (*proot == NULL) /* inserir o elemento - inserting the element */
  175. { if ((*proot = ABPNodeCreate (pelem)) == NULL) return; }
  176. else if ((*proot)->Elem > pelem) /* subarvore esquerda - left subtree */
  177. ABPInsertRec (&(*proot)->PtLeft, pelem);
  178. else if ((*proot)->Elem < pelem) /* subarvore direita - right subtree */
  179. ABPInsertRec (&(*proot)->PtRight, pelem);
  180. else { Error = REP_ELEM; return; } /* o elemento já existe - element already exists */
  181. }
  182.  
  183. /******************************************************************************/
  184.  
  185. void ABPInsertRep (PtABPNode *proot, int pelem) /* inserção repetitiva - repetitive insertion */
  186. {
  187. PtABPNode Node = *proot, Prev = NULL;
  188.  
  189. /* arvore vazia no colocado na raiz desta arvore - empty tree inserting the element */
  190. if (*proot == NULL) { *proot = ABPNodeCreate (pelem); return; }
  191.  
  192. while (Node != NULL) /* travessia até ao local de inserção - traversal looking for the insertion point */
  193. {
  194. Prev = Node;
  195. if (Node->Elem > pelem) Node = Node->PtLeft;
  196. else if (Node->Elem < pelem) Node = Node->PtRight;
  197. else { Error = REP_ELEM; return; } /* repetido não é inserido - already exists not inserted */
  198. }
  199. /* inserir folha à esquerda ou à direita - inserting the leave to the right or the left */
  200. if (Prev->Elem > pelem) Prev->PtLeft = ABPNodeCreate (pelem);
  201. else Prev->PtRight = ABPNodeCreate (pelem);
  202. }
  203.  
  204. /******************************************************************************/
  205.  
  206. void ABPDeleteRec (PtABPNode *proot, int pelem) /* remoção recursiva - recursive deletion */
  207. {
  208. Error = OK;
  209. if (*proot == NULL) { Error = NO_ELEM; return; } /* arvore vazia ou elemento inexistente - empty tree or non existing element */
  210.  
  211. if ((*proot)->Elem > pelem)
  212. ABPDeleteRec (&(*proot)->PtLeft, pelem);
  213. else if ((*proot)->Elem < pelem)
  214. ABPDeleteRec (&(*proot)->PtRight, pelem);
  215. else NodeDelete (proot); /* eliminar o elemento - deleting the element */
  216. }
  217.  
  218. /******************************************************************************/
  219.  
  220. void ABPDeleteRep (PtABPNode *proot, int pelem) /* remoção repetitiva - repetitive deletion */
  221. {
  222. PtABPNode Del = *proot, Prev = NULL, Node, Temp, PrevTemp;
  223.  
  224. if (*proot == NULL) { Error = ABP_EMPTY; return; } /* arvore vazia - empty tree */
  225. while (Del != NULL && Del->Elem != pelem)
  226. { /* travessia até encontrar o elemento a remover - traversal looking for the deletion point */
  227. Prev = Del;
  228. if (Del->Elem > pelem) Del = Del->PtLeft;
  229. else Del = Del->PtRight;
  230. }
  231.  
  232. if (Del == NULL) { Error = NO_ELEM; return; } /* elemento inexistente na arvore - element does ot exist */
  233. Node = Del;
  234.  
  235. Error=OK;
  236. if (Node->PtRight == NULL) Node = Node->PtLeft; /* à esquerda - to the left */
  237. else if (Node->PtLeft == NULL) Node = Node->PtRight; /* à direita - to the right */
  238. else /* com subarvores esquerda e direita - with both subtrees */
  239. { /* procurar menor elemento da subarvore direita - search for the minimum element in the right subtree */
  240. Temp = Node->PtRight; PrevTemp = Node;
  241. while (Temp->PtLeft != NULL)
  242. { PrevTemp = Temp; Temp = Temp->PtLeft; }
  243.  
  244. Node->Elem = Temp->Elem; /* substituir pelo menor elemento - replacing by the minimum element */
  245. /* desligá-lo e ajustar as ligações - disconnected it and adjusting the links */
  246. if (PrevTemp == Node) PrevTemp->PtRight = Temp->PtRight;
  247. else PrevTemp->PtLeft = Temp->PtRight;
  248. ABPNodeDestroy (&Temp); return;
  249. }
  250. /* ajustar o pai do elemento removido que só tem um filho - adjusting the father of the deleted element when it has just a son */
  251. if (Del == *proot) *proot = Node; /* se foi eliminado da raiz - if deletion is from the root */
  252. else if (Prev->PtLeft == Del) Prev->PtLeft = Node;
  253. else Prev->PtRight = Node;
  254. ABPNodeDestroy (&Del);
  255. }
  256.  
  257. /******************************************************************************/
  258.  
  259. PtABPNode ABPCreateFile (char *nomef)
  260. {
  261. PtABPNode ABP; FILE *PtF; unsigned int NElem, I, Elem;
  262.  
  263. /* abertura com validacao do ficheiro para leitura - opening the text file for reading */
  264. if ( (PtF = fopen (nomef, "r")) == NULL) { Error = NO_FILE; return NULL; }
  265.  
  266. ABP = ABPCreate (); /* criação da arvore - creting the empty tree */
  267.  
  268. /* leitura do número de elementos da arvore do ficheiro - reading the number of elements from the text file */
  269. fscanf (PtF, "%u", &NElem);
  270. if (NElem < 1) { Error = OK; fclose (PtF); return NULL; }
  271.  
  272. /* leitura dos valores do ficheiro e carregamento da ABP */
  273. /* reading the elements from the text file and inserting them on the BST */
  274. for (I = 0; I < NElem; I++)
  275. {
  276. fscanf (PtF, "%d", &Elem);
  277. ABPInsertRec (&ABP, Elem);
  278. if (ABPErrorCode () == NO_MEM)
  279. { ABPDestroy (&ABP); Error = NO_MEM; return NULL; }
  280. }
  281.  
  282. fclose (PtF); /* fecho do ficheiro - closing the text file */
  283.  
  284. Error = OK;
  285. return ABP; /* devolve a arvore criada - returning the new tree */
  286. }
  287. /******************************************************************************/
  288.  
  289. void ABPStoreFile (PtABPNode proot, char *nomef)
  290. {
  291. FILE *PtF; unsigned int NElem;
  292.  
  293. /* abertura com validacao do ficheiro para escrita - opening the text file for writing */
  294. if ((PtF = fopen (nomef, "w")) == NULL) { Error = NO_FILE; return ; }
  295.  
  296. NElem = ABPSize (proot);
  297. /* escrita do número de elementos da arvore no ficheiro - writing the tree's size */
  298. fprintf (PtF, "%u\n", NElem);
  299.  
  300. /* escrita dos elementos da arvore no ficheiro - writing the tree's elements */
  301. StoreFilePreOrder (proot, PtF);
  302.  
  303. fclose (PtF); /* fecho do ficheiro - closing the text file */
  304. Error = OK;
  305. }
  306.  
  307. /******************************************************************************/
  308.  
  309. void ABPPreOrderRec (PtABPNode proot) /* travessia em pré-ordem recursiva - recursive pre-order traversal */
  310. {
  311. if (proot != NULL)
  312. {
  313. printf ("%d ", proot->Elem); /* imprimir o elemento - printing the element */
  314. ABPPreOrderRec (proot->PtLeft);
  315. ABPPreOrderRec (proot->PtRight);
  316. }
  317. }
  318.  
  319. /******************************************************************************/
  320.  
  321. void ABPInOrderRec (PtABPNode proot) /* travessia em ordem recursiva - recursive in-order traversal */
  322. {
  323. if (proot != NULL)
  324. {
  325. ABPInOrderRec (proot->PtLeft);
  326. printf ("%d ", proot->Elem); /* imprimir o elemento - printing the element */
  327. ABPInOrderRec (proot->PtRight);
  328. }
  329. }
  330.  
  331. /******************************************************************************/
  332.  
  333. void ABPPostOrderRec (PtABPNode proot) /* travessia em pós-ordem recursiva - recursive post-order traversal */
  334. {
  335. if (proot != NULL)
  336. {
  337. ABPPostOrderRec (proot->PtLeft);
  338. ABPPostOrderRec (proot->PtRight);
  339. printf ("%d ", proot->Elem); /* imprimir o elemento - printing the element */
  340. }
  341. }
  342.  
  343. /******************************************************************************/
  344.  
  345. unsigned int ABPSizeRep (PtABPNode proot) /* cálculo do número de elementos repetitiva - repetitive number of nodes */
  346. {
  347. PtABPNode Node = proot; PtStack Stack; unsigned int Number = 0;
  348.  
  349. if (proot == NULL) { Error = ABP_EMPTY; return 0; } /* arvore vazia - empty tree */
  350.  
  351. if ((Stack = StackCreate (sizeof (PtABPNode))) == NULL) { Error = NO_MEM ; return 0; }
  352. StackPush (Stack, &Node); /* armazenar a raiz - storing the root */
  353.  
  354. while (!StackIsEmpty (Stack)) /* enquanto existirem nos - while there are nodes */
  355. {
  356. StackPop (Stack, &Node); /* recuperar o no - retrieve the node */
  357. Number++; /* contar o no - counting the node */
  358.  
  359. /* armazenar a raiz da subarvore esquerda - storing the left subtree root */
  360. if (Node->PtLeft != NULL) StackPush (Stack, &Node->PtLeft);
  361.  
  362. /* armazenar a raiz da subarvore direita - storing the right subtree root */
  363. if (Node->PtRight != NULL) StackPush (Stack, &Node->PtRight);
  364. }
  365.  
  366. StackDestroy (&Stack); /* destruir a pilha - releasing the stack */
  367.  
  368. Error = OK;
  369. return Number;
  370. }
  371.  
  372. /******************************************************************************/
  373.  
  374. void ABPPreOrderRep (PtABPNode proot) /* travessia em pré-ordem repetitiva - repetitive pre-order traversal */
  375. {
  376. PtABPNode Node = proot; PtStack Stack;
  377.  
  378. if (proot == NULL) { Error = ABP_EMPTY; return; } /* arvore vazia - empty tree */
  379. if ((Stack = StackCreate (sizeof (PtABPNode))) == NULL) { Error = NO_MEM ; return; }
  380.  
  381. StackPush (Stack, &Node); /* armazenar a raiz - storing the root */
  382. while (!StackIsEmpty (Stack)) /* enquanto existirem nos - while there are nodes */
  383. {
  384. StackPop (Stack, &Node); /* recuperar o no - retrieve the node */
  385. printf ("%d ", Node->Elem); /* imprimir o elemento - printing the element */
  386.  
  387. /* colocar a raiz da subarvore direita, caso exista - storing the right subtree root if it exists */
  388. if (Node->PtRight != NULL) StackPush (Stack, &Node->PtRight);
  389.  
  390. /* colocar a raiz da subarvore esquerda, caso exista - storing the left subtree root if it exists */
  391. if (Node->PtLeft != NULL) StackPush (Stack, &Node->PtLeft);
  392. }
  393.  
  394. StackDestroy (&Stack); /* destruir a pilha - releasing the stack */
  395. Error = OK;
  396. }
  397.  
  398. /******************************************************************************/
  399.  
  400. void ABPInOrderRep (PtABPNode proot) /* travessia em in-ordem repetitiva - repetitive in-order traversal */
  401. {
  402. PtABPNode Node = proot; PtStack Stack;
  403.  
  404. if (proot == NULL) { Error = ABP_EMPTY; return; } /* arvore vazia - empty tree */
  405. if ((Stack = StackCreate (sizeof (PtABPNode))) == NULL) { Error = NO_MEM ; return; }
  406. StackPush (Stack, &Node); /* armazenar a raiz - storing the root */
  407.  
  408. while (!StackIsEmpty (Stack))
  409. {
  410. if (Node != NULL) /* não é um no externo - not an external node */
  411. {
  412. Node = Node->PtLeft;
  413. StackPush (Stack, &Node); /* subarvore esquerda - left subtree */
  414. }
  415. else /* é um no externo */
  416. {
  417. StackPop (Stack, &Node); /* retirar e descartar o no externo - retrieve and ignore the external node */
  418. if (!StackIsEmpty (Stack))
  419. {
  420. StackPop (Stack, &Node); /* recuperar o no anterior - retrieve and preview node */
  421. printf ("%d ", Node->Elem); /* imprimir o elemento - printing the element */
  422. Node = Node->PtRight; /* subarvore direita - right subtree */
  423. StackPush (Stack, &Node);
  424. }
  425. }
  426. }
  427.  
  428. StackDestroy (&Stack); /* destruir a pilha - releasing the stack */
  429. Error = OK;
  430. }
  431.  
  432. /******************************************************************************/
  433.  
  434. void ABPPostOrderRep (PtABPNode proot) /* travessia em pós-ordem repetitiva - repetitive post-order traversal */
  435. {
  436. PtABPNode Node = proot, Last = proot; PtStack Stack;
  437.  
  438. if (proot == NULL) { Error = ABP_EMPTY; return; } /* arvore vazia - empty tree */
  439. if ((Stack = StackCreate (sizeof (PtABPNode))) == NULL) { Error = NO_MEM ; return; }
  440.  
  441. while (1) /* enquanto houver elementos para visitar - while there are nodes */
  442. {
  443. /* travessia pela esquerda até atingir a folha mais à esquerda - left traversal until the left most leaf */
  444. while (Node->PtLeft != NULL)
  445. { StackPush (Stack, &Node); Node = Node->PtLeft; }
  446.  
  447. /* se não tem subarvore direita ou já completou a sua travessia - without right subtree or already completed the traversal */
  448. while (Node->PtRight == NULL || Node->PtRight == Last)
  449. {
  450. printf ("%d ", Node->Elem); /* imprimir o elemento - printing the element */
  451. Last = Node; /* assinalar último elemento visitado - marking the last visited element */
  452. /* terminar quando não há mais elementos na pilha - terminate when there are no more elments in the stack */
  453. if (StackIsEmpty (Stack)) { StackDestroy (&Stack); Error = OK; return; }
  454.  
  455. StackPop (Stack, &Node); /* retirar o elemento anterior - retrieve the preview element */
  456. }
  457.  
  458. StackPush (Stack, &Node); /* recolocar o elemento na pilha - restore the element in the stack */
  459. Node = Node->PtRight; /* iniciar travessia da subarvore direita - start the right subtree traversal */
  460. }
  461. }
  462.  
  463. /******************************************************************************/
  464.  
  465. void ABPByLevel (PtABPNode proot) /* travessia por niveis - traversal by levels */
  466. {
  467. PtABPNode Node = proot; PtQueue Queue;
  468.  
  469. if (proot == NULL) { Error = ABP_EMPTY; return; } /* arvore vazia - empty tree */
  470. if ((Queue = QueueCreate (sizeof (PtABPNode))) == NULL) { Error = NO_MEM ; return; }
  471.  
  472. QueueEnqueue (Queue, &Node); /* armazenar a raiz - storing the root */
  473.  
  474. while (!QueueIsEmpty (Queue))
  475. {
  476. QueueDequeue (Queue, &Node); /* retirar o no - retrieve the node */
  477. printf ("%d ", Node->Elem); /* imprimir o elemento - printing the element */
  478.  
  479. /* armazenar a raiz da subarvore esquerda - storing the left subtree root */
  480. if (Node->PtLeft != NULL) QueueEnqueue (Queue, &Node->PtLeft);
  481.  
  482. /* armazenar a raiz da subarvore direita - storing the right subtree root */
  483. if (Node->PtRight != NULL) QueueEnqueue (Queue, &Node->PtRight);
  484. }
  485.  
  486. QueueDestroy (&Queue); /* destruir a fila - releasing the queue */
  487. Error = OK;
  488. }
  489.  
  490. /******************************************************************************/
  491.  
  492. PtABPNode ABPBalance (PtABPNode proot)
  493. {
  494. int *List; PtABPNode NewABP = NULL;
  495. unsigned int Count = 0, n = ABPSize (proot); /* número de nos - number of nodes */
  496.  
  497. if (proot == NULL) { Error = ABP_EMPTY; return NULL; } /* a arvore está vazia - empyt tree */
  498. /* criar a sequência - creating the array */
  499. if ((List = (int *) calloc (n, sizeof (int))) == NULL) { Error = NO_MEM ; return NULL; }
  500.  
  501. Error = OK;
  502. ListInOrder (proot, List, &Count); /* preencher a sequência - filling the array */
  503. Balance (&NewABP, List, 0, n-1); /* balancear a arvore - balancing the tree */
  504. free (List); /* libertar a sequência - releasing the array */
  505.  
  506. return NewABP;
  507. }
  508.  
  509. /******************************************************************************/
  510.  
  511. void ABPDisplay (PtABPNode proot)
  512. {
  513. if (proot == NULL)
  514. { Error = ABP_EMPTY; return; }
  515.  
  516. Display (proot, 1);
  517. Error = OK;
  518. }
  519.  
  520. /******************************************************************************/
  521.  
  522. PtABPNode ABPCopy (PtABPNode proot)
  523. {
  524. PtABPNode Copy;
  525.  
  526. Error = OK;
  527. if (proot == NULL) return NULL;
  528.  
  529. Copy = CopyRec (proot);
  530. if (Error) ABPDestroy (&Copy);
  531.  
  532. return Copy;
  533. }
  534.  
  535. /*********************************** Aula 10 ***********************************/
  536.  
  537. int ABPEmpty (PtABPNode proot)
  538. {
  539. if(proot == NULL) return 1;
  540. return 0;
  541. }
  542.  
  543. int ABPElement (PtABPNode pnode)
  544. {
  545. Error = OK;
  546. if(pnode == NULL)
  547. Error = NULL_PTR;
  548. return pnode->Elem;
  549. }
  550.  
  551.  
  552. PtABPNode ABPMaxRep (PtABPNode proot)
  553. {
  554. if (ABPEmpty(proot)){ Error = ABP_EMPTY; return NULL; }
  555. while(proot->PtRight != NULL) proot = proot->PtRight;
  556. Error = OK;
  557. return proot;
  558. }
  559.  
  560. int ABPTotalSum (PtABPNode proot)
  561. {
  562. int sum = 0; PtABPNode Node = proot; PtQueue Queue;
  563. if (ABPEmpty(proot)){
  564. Error = ABP_EMPTY;
  565. return 0;
  566. }
  567. if ((Queue = QueueCreate (sizeof (PtABPNode))) == NULL){
  568. Error = NO_MEM;
  569. return 0;
  570. }
  571.  
  572. QueueEnqueue (Queue, &Node);
  573. while (!QueueIsEmpty (Queue)){
  574. QueueDequeue (Queue, &Node);
  575. sum += Node->Elem;
  576. if (Node->PtLeft != NULL) QueueEnqueue (Queue, &Node->PtLeft);
  577. if (Node->PtRight != NULL) QueueEnqueue (Queue, &Node->PtRight);
  578. }
  579.  
  580. QueueDestroy (&Queue);
  581. Error = OK;
  582. return sum;
  583. }
  584.  
  585. unsigned int ABPMultCount (PtABPNode proot, int pvalue)
  586. {
  587. PtABPNode aux; PtStack Stack;
  588. int mult = 0;
  589. if(proot == NULL){ Error = ABP_EMPTY; return 0; }
  590. if((Stack=StackCreate(sizeof(PtABPNode))) == NULL) { Error = NO_MEM; return 0; }
  591. StackPush(Stack, (PtABPNode)&proot);
  592.  
  593. while(!StackIsEmpty(Stack)){
  594. StackPop(Stack, (PtABPNode)&aux);
  595. if(aux->Elem % pvalue ==0) mult++;
  596. if(aux->PtRight) StackPush(Stack,(PtABPNode)&aux->PtRight);
  597. if(aux->PtLeft) StackPush(Stack,(PtABPNode)&aux->PtLeft);
  598. }
  599.  
  600. StackDestroy(&Stack);
  601. Error = OK;
  602.  
  603. return mult;
  604. }
  605.  
  606. static int odd = 0;
  607. unsigned int ABPOddCount (PtABPNode proot)
  608. {
  609. if(ABPEmpty(proot)){ Error = ABP_EMPTY; return 0; }
  610. if((proot->Elem % 2) != 0) odd++;
  611. if(proot->PtLeft != NULL) ABPOddCount(proot->PtLeft);
  612. if(proot->PtRight != NULL) ABPOddCount(proot->PtRight);
  613. Error = OK;
  614. return odd;
  615. }
  616.  
  617. static int even;
  618. int ABPEvenSum (PtABPNode proot)
  619. {
  620. if(ABPEmpty(proot)){ Error = ABP_EMPTY; return 0; }
  621. if((proot->Elem % 2) == 0) even += proot->Elem;
  622. if(proot->PtLeft != NULL) ABPEvenSum(proot->PtLeft);
  623. if(proot->PtRight != NULL) ABPEvenSum(proot->PtRight);
  624. Error = OK;
  625. return even;
  626. }
  627.  
  628. int ABPOddOrderSum (PtABPNode proot)
  629. {
  630. if (ABPEmpty(proot)) { Error=ABP_EMPTY; return 0; }
  631. PtABPNode Node = proot; PtStack Stack;
  632. if ((Stack = StackCreate (sizeof (PtABPNode))) == NULL) { Error = NO_MEM ; return 0; }
  633. int oddOrder = 0, sum = 0;
  634. StackPush (Stack, &Node);
  635. while (!StackIsEmpty (Stack))
  636. {
  637. if (Node != NULL)
  638. {
  639. Node = Node->PtLeft;
  640. StackPush (Stack, &Node);
  641. }
  642. else
  643. {
  644. StackPop (Stack, &Node);
  645. if (!StackIsEmpty (Stack))
  646. {
  647. StackPop (Stack, &Node);
  648. oddOrder++;
  649. if(oddOrder%2 != 0)
  650. sum += Node->Elem;
  651. Node = Node->PtRight;
  652. StackPush (Stack, &Node);
  653. }
  654. }
  655. }
  656. StackDestroy (&Stack);
  657. Error = OK;
  658. return sum;
  659. }
  660.  
  661. /******************************************************************************/
  662.  
  663. /************************* Funções internas auxiliares ************************/
  664.  
  665. /*******************************************************************************
  666. Função que cria o no compacto da arvore binária de pesquisa.
  667.  
  668. Function that allocates the dynamic memory for the binary search tree node.
  669. *******************************************************************************/
  670. static PtABPNode ABPNodeCreate (int pelem) /* alocação do no - node allocation */
  671. {
  672. PtABPNode Node;
  673.  
  674. if ((Node = (PtABPNode) malloc (sizeof (struct abpnode))) == NULL)
  675. { Error = NO_MEM; return NULL; }
  676.  
  677. Node->Elem = pelem; /* copiar o elemento - copies the element */
  678. Node->PtLeft = NULL; /* apontar para a esquerda para NULL - empty left subtree */
  679. Node->PtRight = NULL; /* apontar para a direita para NULL - empty right subtree */
  680.  
  681. Error=OK;
  682. return Node;
  683. }
  684.  
  685. /*******************************************************************************
  686. Função que liberta a memoria do no compacto da arvore binária de pesquisa.
  687.  
  688. Function that frees the dynamic memory of the binary search tree node.
  689. *******************************************************************************/
  690. static void ABPNodeDestroy (PtABPNode *pelem) /* libertação do no - node deallocation */
  691. {
  692. free (*pelem); /* libertação do no - frees the node */
  693. *pelem = NULL; /* colocar o ponteiro a nulo - pointing to null */
  694. }
  695.  
  696. /*******************************************************************************
  697. Função recursiva que pesquisa o elemento pretendido na arvore.
  698.  
  699. Recursive function that searches the given element in a tree.
  700. *******************************************************************************/
  701. static PtABPNode SearchRec (PtABPNode proot, int pelem) /* pesquisa recursiva - recursive search */
  702. {
  703. if (proot == NULL) return NULL; /* pesquisa sem sucesso - search without success */
  704.  
  705. if (proot->Elem == pelem) return proot; /* pesquisa com sucesso - search with success */
  706. else if (proot->Elem > pelem)
  707. return SearchRec (proot->PtLeft, pelem);
  708. else return SearchRec (proot->PtRight, pelem);
  709. }
  710.  
  711. /*******************************************************************************
  712. Função repetitiva que pesquisa o elemento pretendido na arvore.
  713.  
  714. Repetitive function that searches the given element in a tree.
  715. *******************************************************************************/
  716. static PtABPNode SearchRep (PtABPNode proot, int pelem) /* pesquisa repetitiva - repetitive search */
  717. {
  718. while (proot != NULL && proot->Elem != pelem)
  719. if (proot->Elem > pelem) proot = proot->PtLeft;
  720. else proot = proot->PtRight;
  721.  
  722. return proot; /* devolver o resultado da pesquisa - returns the result of the search */
  723. }
  724.  
  725. /*******************************************************************************
  726. Função recursiva que pesquisa o K-menor elemento da arvore.
  727.  
  728. Recursive function that selects the K-minimum element of the tree.
  729. *******************************************************************************/
  730. static PtABPNode KMinRec (PtABPNode proot, unsigned int pk)
  731. {
  732. unsigned int NLeft = ABPSize (proot->PtLeft);
  733.  
  734. if (pk == NLeft+1) return proot;
  735. else if (pk <= NLeft) return KMinRec (proot->PtLeft, pk);
  736. else return KMinRec (proot->PtRight, pk-NLeft-1);
  737. }
  738.  
  739. /*******************************************************************************
  740. Função que remove efectivamente um no da arvore.
  741.  
  742. Function that efectively deletes the node.
  743. *******************************************************************************/
  744. static void NodeDelete (PtABPNode *proot)
  745. {
  746. PtABPNode Node = *proot;
  747.  
  748. if ((*proot)->PtLeft == NULL && (*proot)->PtRight == NULL)
  749. ABPNodeDestroy (proot); /* eliminar o elemento que é uma folha - deleting a leaf node */
  750. else if ((*proot)->PtLeft == NULL) /* com subarvore direita - with right subtree only */
  751. {
  752. *proot = (*proot)->PtRight; /* ligar à direita - connect to the right subtree */
  753. ABPNodeDestroy (&Node); /* eliminar o elemento - deleting the node */
  754. }
  755. else if ((*proot)->PtRight == NULL) /* com subarvore esquerda - with left subtree only */
  756. {
  757. *proot = (*proot)->PtLeft; /* ligar à esquerda - connect to the left subtree */
  758. ABPNodeDestroy (&Node); /* eliminar o elemento - deleting the node */
  759. }
  760. else /* com subarvores direita e esquerda - with both right and left subtrees */
  761. { /* substituir pelo menor elemento da subarvore direita - replacing by the minimum element of the right subtree */
  762. (*proot)->Elem = FindMin ((*proot)->PtRight);
  763. /* remover o menor elemento da subarvore direita - deleting the minimum element of the right subtree */
  764. ABPDeleteRec (&(*proot)->PtRight, (*proot)->Elem);
  765. }
  766. }
  767.  
  768. /*******************************************************************************
  769. Função repetitva que pesquisa o no minimo que se encontra na arvore a
  770. partir do no indicado.
  771.  
  772. Repetitive function that searches the minimum element of a tree that starts in
  773. the given node.
  774. *******************************************************************************/
  775. static int FindMin (PtABPNode proot)
  776. {
  777. PtABPNode Node = proot;
  778.  
  779. while (Node->PtLeft != NULL) Node = Node->PtLeft;
  780.  
  781. return Node->Elem; /* devolve um ponteiro para o elemento - returns the pointer to the minimum element */
  782. }
  783.  
  784. /*******************************************************************************
  785. Função recursiva que escreve os elementos da arvore em pre-ordem num ficheiro.
  786.  
  787. Recursive function that makes a pre-order traversal of the tree and writes its
  788. elements in a text file.
  789. *******************************************************************************/
  790. static void StoreFilePreOrder (PtABPNode abp, FILE *fich)
  791. {
  792. if (abp != NULL)
  793. {
  794. fprintf (fich, "%d\n", abp->Elem); /* escreve o elemento no ficheiro - writes the element in the file */
  795.  
  796. StoreFilePreOrder (abp->PtLeft, fich); /* arvore esquerda - left subtree */
  797. StoreFilePreOrder (abp->PtRight, fich); /* arvore direita - right subtree */
  798. }
  799. }
  800.  
  801. /*******************************************************************************
  802. Função recursiva que armazena os elementos da arvore em ordem num array.
  803.  
  804. Recursive function that makes a in-order traversal of the tree and stores its
  805. elements in an array.
  806. *******************************************************************************/
  807. static void ListInOrder (PtABPNode proot, int plist[], unsigned int *pcount)
  808. {
  809. if (proot != NULL)
  810. {
  811. ListInOrder (proot->PtLeft, plist, pcount); /* arvore esquerda - left subtree */
  812. plist[(*pcount)++] = proot->Elem; /* coloca o elemento no array - stores the element in the array */
  813. ListInOrder (proot->PtRight, plist, pcount); /* arvore direita - right subtree */
  814. }
  815. }
  816.  
  817. /*******************************************************************************
  818. Função recursiva que insere os elementos de uma lista numa arvore vazia de modo
  819. que ela fique balanceada.
  820.  
  821. Recursive function that inserts an ordered array of elements in a tree in order
  822. that the is built a balanced tree.
  823. *******************************************************************************/
  824. static void Balance (PtABPNode *proot, int plist[], int pbegin, int pend)
  825. {
  826. unsigned int Median;
  827.  
  828. if (pbegin <= pend)
  829. {
  830. Median = (pbegin + pend) >> 1; /* (pbegin+pend)/2 - calculating the middle position */
  831. ABPInsertRec (proot, plist[Median]); /* inserir elemento central - insert the central element */
  832. Balance (proot, plist, pbegin, Median-1); /* subarvore esquerda - left subtree */
  833. Balance (proot, plist, Median+1, pend); /* subarvore direita - right subtree */
  834. }
  835. }
  836.  
  837. /*******************************************************************************
  838. Função recursiva que escreve os elementos da arvore de forma hierarquica.
  839.  
  840. Recursive function that prints the tree elements in a hierarchical way.
  841. *******************************************************************************/
  842. static void Display (PtABPNode proot, unsigned int plevel)
  843. {
  844. unsigned int i;
  845.  
  846. if (proot == NULL)
  847. {
  848. for (i = 0; i < plevel; i++) printf ("\t");
  849. printf ("*\n");
  850. return;
  851. }
  852.  
  853. Display (proot->PtRight, plevel+1);
  854.  
  855. for (i = 0; i < plevel; i++) printf ("\t");
  856.  
  857. printf ("%d\n", proot->Elem); /* imprimir o elemento - printing the element */
  858.  
  859. Display (proot->PtLeft, plevel+1);
  860. }
  861.  
  862. /*******************************************************************************
  863. Função recursiva que copia uma arvore. Recursive function that copies a tree.
  864. *******************************************************************************/
  865. static PtABPNode CopyRec (PtABPNode proot)
  866. {
  867. PtABPNode Node;
  868.  
  869. if (proot == NULL) return NULL;
  870.  
  871. if ((Node = ABPNodeCreate (proot->Elem)) == NULL) return NULL;
  872.  
  873. if (proot->PtLeft != NULL) Node->PtLeft = CopyRec (proot->PtLeft);
  874. if (!Error && proot->PtRight != NULL) Node->PtRight = CopyRec (proot->PtRight);
  875.  
  876. return Node;
  877. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement