tree.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /****************************************************************************
  2. *
  3. * MODULE: r.describe
  4. *
  5. * AUTHOR(S): Michael Shapiro - CERL
  6. *
  7. * PURPOSE: Prints terse list of category values found in a raster
  8. * map layer.
  9. *
  10. * COPYRIGHT: (C) 2006 by the GRASS Development Team
  11. *
  12. * This program is free software under the GNU General Public
  13. * License (>=v2). Read the file COPYING that comes with GRASS
  14. * for details.
  15. *
  16. ***************************************************************************/
  17. #include <grass/gis.h>
  18. #include <grass/raster.h>
  19. #define INCR 10
  20. #define NCATS 100
  21. typedef struct
  22. {
  23. int idx;
  24. char cat[NCATS];
  25. int left;
  26. int right;
  27. } NODE;
  28. static NODE *tree = 0; /* tree of values */
  29. static int tlen; /* allocated tree size */
  30. static int N; /* number of actual nodes in tree */
  31. int plant_tree(void)
  32. {
  33. N = 0;
  34. if (!tree) {
  35. tlen = INCR;
  36. tree = (NODE *) G_malloc(tlen * sizeof(NODE));
  37. }
  38. return 0;
  39. }
  40. int add_node_to_tree(register CELL cat)
  41. {
  42. register int p, q;
  43. int idx, offset;
  44. if (cat < 0) {
  45. idx = -(-cat / NCATS) - 1;
  46. offset = cat - idx * NCATS - 1;
  47. }
  48. else {
  49. idx = cat / NCATS;
  50. offset = cat - idx * NCATS;
  51. }
  52. if (offset < 0 || offset >= NCATS)
  53. G_warning("cat %ld got offset %d - shouldn't happen", (long)cat,
  54. offset);
  55. /* first node is special case */
  56. if (N == 0) {
  57. N = 1;
  58. G_zero(tree[N].cat, sizeof(tree[N].cat));
  59. tree[N].idx = idx;
  60. tree[N].cat[offset] = 1;
  61. tree[N].left = 0;
  62. tree[N].right = 0;
  63. return 0;
  64. }
  65. q = 1;
  66. while (q > 0) {
  67. p = q;
  68. if (tree[q].idx == idx) {
  69. tree[q].cat[offset] = 1;
  70. return 0; /* found */
  71. }
  72. if (tree[q].idx > idx)
  73. q = tree[q].left; /* go left */
  74. else
  75. q = tree[q].right; /* go right */
  76. }
  77. /* new node */
  78. N++;
  79. /* grow the tree? */
  80. if (N >= tlen)
  81. tree = (NODE *) G_realloc(tree, sizeof(NODE) * (tlen += INCR));
  82. /* add node to tree */
  83. G_zero(tree[N].cat, sizeof(tree[N].cat));
  84. tree[N].idx = idx;
  85. tree[N].cat[offset] = 1;
  86. tree[N].left = 0;
  87. if (tree[p].idx > idx) {
  88. tree[N].right = -p; /* create thread */
  89. tree[p].left = N; /* insert left */
  90. }
  91. else {
  92. tree[N].right = tree[p].right; /* copy right link/thread */
  93. tree[p].right = N; /* add right */
  94. }
  95. return 0;
  96. }
  97. static int curp;
  98. #ifdef COMMENT_OUT
  99. static int curoffset;
  100. #endif
  101. int first_node(void)
  102. {
  103. int q;
  104. /* start at root and go all the way to the left */
  105. curp = 1;
  106. while ((q = tree[curp].left))
  107. curp = q;
  108. return 0;
  109. }
  110. int next_node(void)
  111. {
  112. int q;
  113. /* go to the right */
  114. curp = tree[curp].right;
  115. if (curp == 0) /* no more */
  116. return 0;
  117. if (curp < 0) { /* thread. stop here */
  118. curp = -curp;
  119. return 1;
  120. }
  121. while ((q = tree[curp].left)) /* now go all the way left */
  122. curp = q;
  123. return 1;
  124. }
  125. #ifdef COMMENT_OUT
  126. int first_cat(CELL * cat)
  127. {
  128. first_node();
  129. curoffset = -1;
  130. return next_cat(cat);
  131. }
  132. int next_cat(CELL * cat)
  133. {
  134. int idx;
  135. for (;;) {
  136. curoffset++;
  137. if (curoffset >= NCATS) {
  138. if (!next_node())
  139. return 0;
  140. curoffset = -1;
  141. continue;
  142. }
  143. if (tree[curp].cat[curoffset]) {
  144. idx = tree[curp].idx;
  145. if (idx < 0)
  146. *cat = idx * NCATS + curoffset + 1;
  147. else
  148. *cat = idx * NCATS + curoffset;
  149. return 1;
  150. }
  151. }
  152. return 0;
  153. }
  154. #endif