00001
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
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
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
00192
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
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 = ∅
00232 UInt32 nbrNodesFullList = NbrNodes(*linkedList);
00233
00234
00235 listA = *linkedList;
00236 listB = SplitAtNth(listA, nbrNodesFullList/2);
00237
00238
00239 if (floor((double)(nbrNodesFullList)/2) > 1)
00240 SplitAndMergeSort(&listA, CompareFunction);
00241 if (ceil((double)(nbrNodesFullList)/2) > 1)
00242 SplitAndMergeSort(&listB, CompareFunction);
00243
00244
00245 while (listA && listB)
00246 {
00247 if (CompareFunction(listA, listB) < 0)
00248 {
00249
00250 curNode->next = listA;
00251 curNode = curNode->next;
00252 listA = listA->next;
00253 }
00254 else
00255 {
00256
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