Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals  

LinkedLists.c

Go to the documentation of this file.
00001 /* Single and indirect linked lists.*/
00002 
00013 #include <stdlib.h>
00014 #include <math.h>
00015 #include "LinkedLists.h"
00016 
00018 
00024 UInt32 DestroyLinkedList(NodePtr linkedList, UInt8 (*DestructorFunction)(NodePtr theNode))
00025 {
00026   
00027   NodePtr curNode, copyPtr;
00028   UInt32 nbrDestroyed = 0;
00029   if (!DestructorFunction)
00030     return 0;
00031   for (curNode = linkedList; curNode;)
00032   {
00033     copyPtr = curNode->next;
00034     if (DestructorFunction(curNode))
00035       return nbrDestroyed;
00036     nbrDestroyed++;
00037     curNode = copyPtr;
00038   }
00039   return nbrDestroyed;
00040 }
00041 
00043 UInt8 DestroyIndirectNode(NodePtr theNode)
00044 {
00045   free((IndirectNodePtr)(theNode));
00046   return (!theNode);
00047 }
00048 
00050 
00057 UInt32 FindLast(NodePtr linkedList, NodePtr* last)
00058 {
00059   
00060   NodePtr curNode;
00061   UInt32 nbrNodes = 0;
00062   for (curNode = linkedList; curNode->next; curNode = curNode->next)
00063     nbrNodes++;
00064   if (last)
00065     *last = curNode;
00066   return (nbrNodes + 1);
00067 }
00068 
00070 
00074 NodePtr GetNthNode(NodePtr linkedList, UInt32 n)
00075 {
00076   NodePtr curNode = linkedList;
00077   while ( (n--) && (curNode) )
00078     curNode = curNode->next;
00079   return curNode;
00080 }
00081 
00083 
00088 NodePtr SplitAtNth(NodePtr linkedList, UInt32 n)
00089 {
00090   UInt32 curPos = 0;
00091   NodePtr curNode, copyPtr;
00092   for (curNode = linkedList; (++curPos) != n; curNode = curNode->next)
00093   {
00094     if (!curPos)
00095       return NULL;
00096   }
00097   copyPtr = curNode->next;
00098   curNode->next = NULL;
00099   return copyPtr;
00100 }
00101 
00103 
00111 IndirectNodePtr FindAndList(NodePtr linkedList, UInt8 (*IsWhatIWant)(NodePtr theNode))
00112 {
00113   NodePtr curNode;
00114   IndirectNodePtr foundList = NULL, lastInFoundList = NULL;
00115   if (!IsWhatIWant)
00116     return NULL;
00117   for(curNode = linkedList; curNode; curNode = curNode->next)
00118   {
00119     if (IsWhatIWant(curNode))
00120     {
00121       IndirectNodePtr newNode = malloc(sizeof(IndirectNode));
00122       newNode->nodePtr = curNode;
00123       if (!foundList)
00124       {
00125   foundList = newNode;
00126   lastInFoundList = newNode;
00127       }
00128       else
00129       {
00130   lastInFoundList->nodeHeader.next = (Node*)(newNode);
00131   lastInFoundList = newNode;
00132       }
00133       lastInFoundList->nodeHeader.next = NULL;
00134     }
00135   }
00136   return foundList;
00137 }
00138 
00140 
00145 NodePtr FindAndMoveOut(NodePtr *linkedListPtr, UInt8 (*IsWhatIWant)(NodePtr theNode))
00146 {
00147   NodePtr *curNodePtrPtr, newList;
00148   IndirectNodePtr foundList = FindAndList(*linkedListPtr, IsWhatIWant), curIndirect;
00149   if (!foundList)
00150     return NULL;
00151   curIndirect = foundList;
00152   for(curNodePtrPtr = linkedListPtr; *curNodePtrPtr;)
00153   {
00154     if (*curNodePtrPtr == curIndirect->nodePtr)
00155     {
00156       *curNodePtrPtr = (*curNodePtrPtr)->next;
00157       /* Searching for next one */
00158       curIndirect = (IndirectNodePtr)(curIndirect->nodeHeader.next);
00159       if (!curIndirect)
00160   break;
00161     }
00162     else
00163     {
00164       curNodePtrPtr = &((*curNodePtrPtr)->next);
00165     }
00166   }
00167   ApplyIndirectOnSimple(foundList);
00168   newList = foundList->nodePtr;
00169   /* Destroying temporary indirect linked list... */
00170   DestroyLinkedList((Node*)(foundList), DestroyIndirectNode);
00171   return newList;
00172 }
00173 
00175 
00182 void ApplyIndirectOnSimple(IndirectNodePtr indirectList)
00183 {
00184   IndirectNodePtr curIndirect;
00185   for (curIndirect = indirectList; curIndirect->nodeHeader.next;
00186        curIndirect = (IndirectNodePtr)(curIndirect->nodeHeader.next))
00187   {
00188     curIndirect->nodePtr->next =
00189     ((IndirectNodePtr)(curIndirect->nodeHeader.next))->nodePtr;
00190   }
00191   /* Do the last one. Otherwise ((IndirectNodePtr)(curIndirect->nodeHeader.next))->nodePtr */
00192   /* is just junk from *NULL... */
00193   curIndirect->nodePtr->next = NULL;
00194 }
00195 
00197 
00203 void InvertList(NodePtr *linkedListPtr)
00204 {
00205   NodePtr newList, lastNode;
00206   UInt32 nbrNodes = NbrNodes(*linkedListPtr), curNth;
00207   if (nbrNodes < 2)
00208     return;
00209   lastNode = newList = GetNthNode(*linkedListPtr, nbrNodes-1);
00210   for (curNth = (nbrNodes - 2); curNth; curNth--)
00211   {
00212     lastNode->next = GetNthNode(*linkedListPtr, curNth);
00213     lastNode = lastNode->next;
00214   }
00215   /* Add the last one. */
00216   lastNode->next = *linkedListPtr;
00217   (*linkedListPtr)->next = NULL;
00218   *linkedListPtr = newList;
00219 }
00220 
00222 
00228 void SplitAndMergeSort(NodePtr *linkedList, SInt8 (*CompareFunction)(NodePtr a, NodePtr b))
00229 {
00230   Node empty;
00231   NodePtr listA, listB, curNode = &empty, newList = &empty;
00232   UInt32 nbrNodesFullList = NbrNodes(*linkedList);
00233   
00234   /* Split... */
00235   listA = *linkedList;
00236   listB = SplitAtNth(listA, nbrNodesFullList/2);
00237   
00238   /* ...(sorting)... */
00239   if (floor((double)(nbrNodesFullList)/2) > 1) /* Size of listA */
00240     SplitAndMergeSort(&listA, CompareFunction);
00241   if (ceil((double)(nbrNodesFullList)/2) > 1) /* Size of listB */
00242     SplitAndMergeSort(&listB, CompareFunction);
00243   
00244   /* ... and Merge */
00245   while (listA && listB)
00246   {
00247     if (CompareFunction(listA, listB) < 0)
00248     {
00249       /* listA is smaller than listB */
00250       curNode->next = listA;
00251       curNode = curNode->next;
00252       listA = listA->next;
00253     }
00254     else
00255     {
00256       /* listB is smaller or equal to listA */
00257       curNode->next = listB;
00258       curNode = curNode->next;
00259       listB = listB->next;
00260     }
00261   }
00262   while (listA)
00263   {
00264     curNode->next = listA;
00265     curNode = curNode->next;
00266     listA = listA->next;
00267   }
00268   while (listB)
00269   {
00270     curNode->next = listB;
00271     curNode = curNode->next;
00272     listB = listB->next;
00273   }
00274   newList = newList->next;
00275   *linkedList = newList;
00276 }
00277 

Generated on Sun Dec 23 15:20:37 2001 for ANet by doxygen 1.2.12 written by Dimitri van Heesch, © 1997-2001

SourceForge
Logo