Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

258 lines
5.9 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. /*************************************************************************
  3. *
  4. * TREE.C
  5. *
  6. * Binary tree routines
  7. *
  8. *
  9. *************************************************************************/
  10. /*
  11. * Includes
  12. */
  13. #include <windows.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include "qappsrv.h"
  18. /*=============================================================================
  19. == Local Structures
  20. =============================================================================*/
  21. typedef struct _TREENODE {
  22. WCHAR Name[MAXNAME];
  23. WCHAR Address[MAXADDRESS];
  24. struct _TREENODE * pLeft;
  25. struct _TREENODE * pRight;
  26. struct _TREENODE * pParent;
  27. } TREENODE, * PTREENODE;
  28. /*=============================================================================
  29. == Local data
  30. =============================================================================*/
  31. static PTREENODE G_pRoot = NULL;
  32. /*=============================================================================
  33. == Global Data
  34. =============================================================================*/
  35. extern USHORT fAddress;
  36. /*=============================================================================
  37. == External Functions Defined
  38. =============================================================================*/
  39. int TreeAdd( LPTSTR, LPTSTR );
  40. void TreeTraverse( PTREETRAVERSE );
  41. /*=============================================================================
  42. == Private Functions Defined
  43. =============================================================================*/
  44. PTREENODE _Tree_GetNext(PTREENODE pCurr);
  45. PTREENODE _Tree_GetFirst(PTREENODE pRoot);
  46. /*******************************************************************************
  47. *
  48. * TreeAdd
  49. *
  50. *
  51. * ENTRY:
  52. * pName (input)
  53. * pointer to name to add
  54. * pAddress (input)
  55. * pointer to address to add
  56. *
  57. * EXIT:
  58. * ERROR_SUCCESS - no error
  59. *
  60. ******************************************************************************/
  61. int
  62. TreeAdd( LPTSTR pName, LPTSTR pAddress )
  63. {
  64. PTREENODE pCurr = G_pRoot;
  65. PTREENODE pNext;
  66. PTREENODE pNewNode;
  67. int cmp;
  68. /*
  69. * Allocate tree node structure
  70. */
  71. if ( (pNewNode = malloc(sizeof(TREENODE))) == NULL )
  72. return( ERROR_NOT_ENOUGH_MEMORY );
  73. /*
  74. * Initialize new tree node
  75. */
  76. memset( pNewNode, 0, sizeof(TREENODE) );
  77. lstrcpyn( pNewNode->Name, pName, MAXNAME );
  78. lstrcpyn( pNewNode->Address, pAddress, MAXADDRESS );
  79. /*
  80. * If root is null, then we are done
  81. */
  82. if ( G_pRoot == NULL ) {
  83. G_pRoot = pNewNode;
  84. } else {
  85. /*
  86. * walk current tree in order
  87. */
  88. for (;;) {
  89. cmp = wcscmp( pName, pCurr->Name );
  90. // if entry already exists, don't add
  91. if ( cmp == 0 && (!fAddress || !wcscmp( &pAddress[10], &pCurr->Address[10] )) ) {
  92. free( pNewNode );
  93. return( ERROR_SUCCESS );
  94. }
  95. // greater than lexicographically go right else left
  96. if ( cmp < 0 ) {
  97. // at end of line, then insert
  98. if ( (pNext = pCurr->pLeft) == NULL ) {
  99. pCurr->pLeft = pNewNode;
  100. pNewNode->pParent = pCurr;
  101. break;
  102. }
  103. } else {
  104. // at end of line, then insert
  105. if ( (pNext = pCurr->pRight) == NULL ) {
  106. pCurr->pRight = pNewNode;
  107. pNewNode->pParent = pCurr;
  108. break;
  109. }
  110. }
  111. // next
  112. pCurr = pNext;
  113. }
  114. }
  115. return( ERROR_SUCCESS );
  116. }
  117. /*******************************************************************************
  118. *
  119. * TreeTraverse
  120. *
  121. *
  122. * ENTRY:
  123. * pFunc (input)
  124. * pointer to traverse function
  125. *
  126. * EXIT:
  127. * nothing
  128. *
  129. * History: Date Author Comment
  130. * 2/08/01 skuzin Changed to use non-recursive algorithm
  131. ******************************************************************************/
  132. void
  133. TreeTraverse( PTREETRAVERSE pFunc )
  134. {
  135. PTREENODE pNode;
  136. if(G_pRoot)
  137. {
  138. pNode = _Tree_GetFirst(G_pRoot);
  139. while(pNode)
  140. {
  141. /*
  142. * Call function with name
  143. */
  144. (*pFunc)( pNode->Name, pNode->Address );
  145. pNode=_Tree_GetNext(pNode);
  146. }
  147. }
  148. }
  149. /*******************************************************************************
  150. *
  151. * _Tree_GetFirst()
  152. *
  153. * Finds the leftmost node of the tree
  154. *
  155. * ENTRY:
  156. * PTREENODE pRoot
  157. * pointer to the root node
  158. *
  159. * EXIT:
  160. * pointer to the leftmost node of the tree
  161. *
  162. * History: Date Author Comment
  163. * 2/08/01 skuzin Created
  164. ******************************************************************************/
  165. PTREENODE
  166. _Tree_GetFirst(
  167. IN PTREENODE pRoot)
  168. {
  169. PTREENODE pNode = pRoot;
  170. while(pNode->pLeft)
  171. {
  172. pNode = pNode->pLeft;
  173. }
  174. return pNode;
  175. }
  176. /*******************************************************************************
  177. *
  178. * _Tree_GetFirst()
  179. *
  180. * Finds the next leftmost node of the tree
  181. *
  182. * ENTRY:
  183. * PTREENODE pCurr
  184. * pointer to the the previous leftmost node
  185. *
  186. * EXIT:
  187. * pointer to the next leftmost node of the tree
  188. *
  189. * History: Date Author Comment
  190. * 2/08/01 skuzin Created
  191. ******************************************************************************/
  192. PTREENODE
  193. _Tree_GetNext(
  194. IN PTREENODE pCurr)
  195. {
  196. PTREENODE pNode = pCurr;
  197. if(pNode->pRight)
  198. {
  199. pNode = pNode->pRight;
  200. while(pNode->pLeft)
  201. {
  202. pNode = pNode->pLeft;
  203. }
  204. return pNode;
  205. }
  206. else
  207. {
  208. while(pNode->pParent && pNode->pParent->pLeft != pNode)
  209. {
  210. pNode = pNode->pParent;
  211. }
  212. return pNode->pParent;
  213. }
  214. }