source: tags/arb_5.0/ptpan/dlist.cxx

Last change on this file was 5566, checked in by boehnel, 16 years ago

Adding PTPan

File size: 5.2 KB
Line 
1/************************************************************************
2 Doubly linked list stuff (implementation similar to AmigaOS lists)
3 Written by Chris Hodges <hodges@in.tum.de>.
4 Last change: 26.08.03
5 ************************************************************************/
6
7/* Implementation */
8
9#include <stdio.h>
10#include <stdlib.h>
11#include "dlist.h"
12
13/* /// "NewList()" */
14/* Initialize empty list */
15void NewList(struct List *lh)
16{
17  lh->lh_TailPred = (struct Node *) lh;
18  lh->lh_Tail = NULL;
19  lh->lh_Head = (struct Node *) &lh->lh_Tail;
20}
21/* \\\ */
22
23/* /// "AddHead()" */
24/* Add node to the bottom of the list */
25void AddHead(struct List *lh, struct Node *nd)
26{
27  struct Node *oldhead = lh->lh_Head;
28  lh->lh_Head = nd;
29  nd->ln_Pred = (struct Node *) &lh->lh_Head;
30  nd->ln_Succ = oldhead;
31  oldhead->ln_Pred = nd;
32}
33/* \\\ */
34
35/* /// "AddTail()" */
36/* Add node at the front of the list */
37void AddTail(struct List *lh, struct Node *nd)
38{
39  struct Node *oldtail = lh->lh_TailPred;
40  lh->lh_TailPred = nd;
41  nd->ln_Succ = (struct Node *) &lh->lh_Tail;
42  nd->ln_Pred = oldtail;
43  oldtail->ln_Succ = nd;
44}
45/* \\\ */
46
47/* /// "Remove()" */
48/* Remove node from whatever list it is in */
49void Remove(struct Node *nd)
50{
51  nd->ln_Pred->ln_Succ = nd->ln_Succ;
52  nd->ln_Succ->ln_Pred = nd->ln_Pred;
53}
54/* \\\ */
55
56/* /// "NodePriCompare()" */
57/* compare function for node sorting */
58LONG NodePriCompare(const struct Node **node1, const struct Node **node2)
59{
60  if((*node1)->ln_Pri < (*node2)->ln_Pri)
61  {
62    return(-1);
63  }   
64  if((*node1)->ln_Pri > (*node2)->ln_Pri)
65  {
66    return(1);
67  }   
68  return(0);
69}
70/* \\\ */
71
72/* /// "SortList()" */
73BOOL SortList(struct List *lh)
74{
75  struct Node *ln;
76  struct Node **tmparr;
77  struct Node **arrptr;
78  BOOL sorted = TRUE;
79  ULONG numelem = 0;
80
81  /* count elements and check, if they are sorted already */
82  ln = lh->lh_Head;
83  while(ln->ln_Succ)
84  {
85    numelem++;
86    if(ln->ln_Succ->ln_Succ)
87    {
88      if(ln->ln_Succ->ln_Pri < ln->ln_Pri)
89      {
90       sorted = FALSE;
91      }
92    }
93    ln = ln->ln_Succ;
94  }
95  if(sorted || (numelem < 2))
96  {
97    return(TRUE); /* was already sorted */
98  }
99
100  /* allocate a temporary array */
101  tmparr = (struct Node **) calloc(numelem, sizeof(struct Node *));
102  if(!tmparr)
103  {
104    return(FALSE); /* out of memory */
105  }
106
107  /* enter all elements */
108  arrptr = tmparr;
109  ln = lh->lh_Head;
110  while(ln->ln_Succ)
111  {
112    *arrptr++ = ln;
113    ln = ln->ln_Succ;
114  }
115  /* sort elements */
116  //printf("Sorting...\n");
117  qsort(tmparr, numelem, sizeof(struct Node *),
118        (int (*)(const void *, const void *)) NodePriCompare);
119  /* rebuild list */
120  NewList(lh);
121  arrptr = tmparr;
122  do
123  {
124    AddTail(lh, *arrptr++);
125  } while(--numelem);
126  free(tmparr);
127  return(TRUE);
128}
129/* \\\ */
130
131/* /// "BuildBinTreeRec()" */
132struct BinTree * BuildBinTreeRec(struct Node **nodearr, ULONG left, ULONG right)
133{
134  struct BinTree *bt;
135  ULONG mid;
136  if(left >= right)
137  {
138    return(NULL);
139  }
140  mid = (left + right) >> 1;
141  bt = (struct BinTree *) calloc(sizeof(struct BinTree), 1);
142  if(!bt)
143  {
144    return(NULL); /* out of memory */
145  }
146
147  /* fill children and leaves */
148  bt->bt_Key = nodearr[mid+1]->ln_Pri;
149  bt->bt_Child[0] = BuildBinTreeRec(nodearr, left, mid);
150  if(!bt->bt_Child[0])
151  {
152    bt->bt_Leaf[0] = nodearr[left];
153  }
154  bt->bt_Child[1] = BuildBinTreeRec(nodearr, mid+1, right);
155  if(!bt->bt_Child[1])
156  {
157    bt->bt_Leaf[1] = nodearr[mid+1];
158  }
159  return(bt);
160}
161/* \\\ */
162
163/* /// "BuildBinTree()" */
164struct BinTree * BuildBinTree(struct List *list)
165{
166  struct BinTree *bt;
167  struct Node *ln;
168  struct Node **tmparr;
169  struct Node **arrptr;
170  BOOL sorted = TRUE;
171  ULONG numelem = 0;
172
173  /* count elements */
174  ln = list->lh_Head;
175  while(ln->ln_Succ)
176  {
177    numelem++;
178    ln = ln->ln_Succ;
179  }
180  /* allocate a temporary array */
181  tmparr = (struct Node **) calloc(numelem, sizeof(struct Node *));
182  if(!tmparr)
183  {
184    return(NULL); /* out of memory */
185  }
186
187  /* enter all elements and check, if they are sorted already */
188  arrptr = tmparr;
189  ln = list->lh_Head;
190  while(ln->ln_Succ)
191  {
192    *arrptr++ = ln;
193    if(ln->ln_Succ->ln_Succ)
194    {
195      if(ln->ln_Succ->ln_Pri < ln->ln_Pri)
196      {
197        sorted = FALSE;
198      }
199    }
200    ln = ln->ln_Succ;
201  }
202  if(!sorted) /* only sort the array, if it wasn't sorted before */
203  {
204    /* enter elements */
205    //printf("Sorting...\n");
206    qsort(tmparr, numelem, sizeof(struct Node *),
207        (int (*)(const void *, const void *)) NodePriCompare);
208  }
209  /* build up the tree */
210  bt = BuildBinTreeRec(tmparr, 0, numelem-1);
211  free(tmparr);
212  return(bt);
213}
214/* \\\ */
215
216/* /// "FreeBinTree()" */
217void FreeBinTree(struct BinTree *root)
218{
219  if(!root)
220  {
221    return;
222  }
223  FreeBinTree(root->bt_Child[0]);
224  FreeBinTree(root->bt_Child[1]);
225  free(root);
226}
227/* \\\ */
228
229/* /// "FindBinTreeLowerKey()" */
230struct Node *FindBinTreeLowerKey(struct BinTree *root, LLONG key)
231{
232  if(root->bt_Key > key)
233  {
234    if(root->bt_Leaf[0])
235    {
236      return(root->bt_Leaf[0]);
237    }
238    if(root->bt_Child[0])
239    {
240      return(FindBinTreeLowerKey(root->bt_Child[0], key));
241    }
242  }
243  if(root->bt_Leaf[1])
244  {
245    return(root->bt_Leaf[1]);
246  }
247  if(root->bt_Child[1])
248  {
249    return(FindBinTreeLowerKey(root->bt_Child[1], key));
250  }
251  printf("Huh! Key %lld not found!\n", key);
252  return(NULL);
253}
Note: See TracBrowser for help on using the repository browser.