Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of LinkedList by
LinkedList.h
00001 /** 00002 * @file LinkedList.h 00003 * @brief Core Utility - Templated Linked List class 00004 * @author sam grove 00005 * @version 1.0 00006 * @see 00007 * 00008 * Copyright (c) 2013 00009 * 00010 * Licensed under the Apache License, Version 2.0 (the "License"); 00011 * you may not use this file except in compliance with the License. 00012 * You may obtain a copy of the License at 00013 * 00014 * http://www.apache.org/licenses/LICENSE-2.0 00015 * 00016 * Unless required by applicable law or agreed to in writing, software 00017 * distributed under the License is distributed on an "AS IS" BASIS, 00018 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00019 * See the License for the specific language governing permissions and 00020 * limitations under the License. 00021 */ 00022 00023 #ifndef LINKEDLIST_H_ 00024 #define LINKEDLIST_H_ 00025 00026 #include <stdint.h> 00027 #include "mbed.h" 00028 00029 #define DBG_LLIST 0 00030 00031 #if DBG_LLIST 00032 // #define DBG(...) do{debug("[%s:%d]", __PRETTY_FUNCTION__,__LINE__);debug(__VA_ARGS__);} while(0); 00033 #define DBG(...) do{debug("[DBG ][ll ]");debug(__VA_ARGS__);} while(0); 00034 #else 00035 #define DBG(...) while(0); 00036 #endif 00037 00038 /** 00039 * @struct node 00040 * @brief The Linked List structure 00041 */ 00042 template<typename T> 00043 struct node 00044 { 00045 T *data ; /*!< pointer to list member data */ 00046 struct node *next ; /*!< pointer to the next list member */ 00047 }; 00048 00049 ///** Returns true if data1 shall be inserted before data 2. 00050 //*/ 00051 //typedef bool insertAtFunc(void *data1, void *data2); 00052 00053 /** Example using the LinkedList Class 00054 * @code 00055 * #include "mbed.h" 00056 * #include "LinkedList.h" 00057 * 00058 * LinkedList<node>list; 00059 * 00060 * int main() 00061 * { 00062 * node *tmp; 00063 * 00064 * list.push((char *)"Two\n"); 00065 * list.append((char *)"Three\n"); 00066 * list.append((char *)"Four\n"); 00067 * list.push((char*)"One\n"); 00068 * list.append((char*)"Five\n"); 00069 * 00070 * for(int i=1; i<=list.length(); i++) 00071 * { 00072 * tmp = list.pop(i); 00073 * printf("%s", (char *)tmp->data); 00074 * } 00075 * 00076 * error("done\n"); 00077 * } 00078 * @endcode 00079 */ 00080 00081 /** Example using new insertOrdered function: 00082 * @code 00083 00084 #include "mbed.h" 00085 #include "LinkedList.h" 00086 00087 void printList(LinkedList<node> &list, const char* msg) 00088 { 00089 printf("%s: ", msg); 00090 for(int i=1; i<=list.length(); i++) 00091 { 00092 node *tmp = list.pop(i); 00093 printf("%d ", *(int*)tmp->data); 00094 } 00095 printf("\n"); 00096 } 00097 00098 bool ascending(int *n1, int *n2) 00099 { 00100 int *d1 = (int*)n1; 00101 int *d2 = (int*)n2; 00102 bool rv = *d1 <= *d2; 00103 printf("(%d %d:%d)", *d1, *d2, rv); 00104 return rv; 00105 } 00106 00107 void testAscending() 00108 { 00109 node<int> *tmp; 00110 00111 int n0 = 0; 00112 int n1 = 1; 00113 int n1B = 1; 00114 int n2 = 2; 00115 int n3 = 3; 00116 int n4 = 4; 00117 00118 LinkedList<int>list; 00119 00120 tmp = list.insertOrdered(&n2, ascending); 00121 if (NULL == tmp) { 00122 error("insertOrdered did not insert a node"); 00123 } 00124 printList(list, "exp 2"); 00125 00126 tmp = list.insertOrdered(&n1, ascending); 00127 if (NULL == tmp) { 00128 error("insertOrdered did not insert a node"); 00129 } 00130 printList(list, "exp 1,2"); 00131 00132 tmp = list.insertOrdered(&n4, ascending); 00133 if (NULL == tmp) { 00134 error("insertOrdered did not insert a node"); 00135 } 00136 printList(list, "exp 1,2,4"); 00137 00138 tmp = list.insertOrdered(&n3, ascending); 00139 if (NULL == tmp) { 00140 error("insertOrdered did not insert a node"); 00141 } 00142 printList(list, "exp 1,2,3,4"); 00143 00144 tmp = list.insertOrdered(&n0, ascending); 00145 if (NULL == tmp) { 00146 error("insertOrdered did not insert a node"); 00147 } 00148 printList(list, "exp 0,1,2,3,4"); 00149 00150 tmp = list.insertOrdered(&n1B, ascending); 00151 if (NULL == tmp) { 00152 error("insertOrdered did not insert a node"); 00153 } 00154 printList(list, "exp 0,1,1,2,3,4"); 00155 00156 tmp = list.pop(2); 00157 if (tmp->data != &n1) { 00158 error("pos 2 is not n1\n"); 00159 } 00160 printf("n1 is good\n"); 00161 00162 tmp = list.pop(3); 00163 if (tmp->data != &n1B) { 00164 error("pos3 is not n1B"); 00165 } 00166 printf("n1B is good\n"); 00167 } 00168 00169 bool descending(int *n1, int *n2) 00170 { 00171 int *d1 = (int*)n1; 00172 int *d2 = (int*)n2; 00173 bool rv = *d1 <= *d2; 00174 printf("(%d %d:%d)", *d1, *d2, rv); 00175 return rv; 00176 } 00177 00178 void testDescending() 00179 { 00180 node<int> *tmp; 00181 00182 int n0 = 0; 00183 int n1 = 1; 00184 int n1B = 1; 00185 int n2 = 2; 00186 int n3 = 3; 00187 int n4 = 4; 00188 00189 LinkedList<int>l; 00190 00191 tmp = l.insertOrdered(&n2, descending); 00192 if (NULL == tmp) { 00193 error("insertOrdered did not insert a node"); 00194 } 00195 printList(l, "exp 2"); 00196 00197 tmp = l.insertOrdered(&n1, descending); 00198 if (NULL == tmp) { 00199 error("insertOrdered did not insert a node"); 00200 } 00201 printList(l, "exp 2,1"); 00202 00203 tmp = l.insertOrdered(&n4, descending); 00204 if (NULL == tmp) { 00205 error("insertOrdered did not insert a node"); 00206 } 00207 printList(l, "exp 4,2,1"); 00208 00209 tmp = l.insertOrdered(&n3, descending); 00210 if (NULL == tmp) { 00211 error("insertOrdered did not insert a node"); 00212 } 00213 printList(l, "exp 4,3,2,1"); 00214 00215 tmp = l.insertOrdered(&n0, descending); 00216 if (NULL == tmp) { 00217 error("insertOrdered did not insert a node"); 00218 } 00219 printList(l, "exp 4,3,2,1,0"); 00220 00221 tmp = l.insertOrdered(&n1B, descending); 00222 if (NULL == tmp) { 00223 error("insertOrdered did not insert a node"); 00224 } 00225 printList(l, "exp 4,3,2,1,1,0"); 00226 00227 tmp = l.pop(4); 00228 if (tmp->data != &n1) { 00229 error("pos 2 is not n1\n"); 00230 } 00231 printf("n1 is good\n"); 00232 00233 tmp = l.pop(5); 00234 if (tmp->data != &n1B) { 00235 error("pos3 is not n1B"); 00236 } 00237 printf("n1B is good\n"); 00238 } 00239 00240 00241 int main() 00242 { 00243 printf("\nJob Scheduler Demo\n"); 00244 00245 testDescending(); 00246 00247 error("done\n"); 00248 00249 exit(0); 00250 } 00251 00252 00253 00254 * @endcode 00255 */ 00256 00257 /** 00258 * @class LinkedList 00259 * @brief API abstraction for a Linked List 00260 */ 00261 template<typename T> 00262 class LinkedList 00263 { 00264 protected: 00265 node<T> *_head; 00266 00267 public: 00268 /** Create the LinkedList object 00269 */ 00270 LinkedList() { 00271 // clear the member 00272 _head = 0; 00273 } 00274 00275 00276 /** Deconstructor for the LinkedList object 00277 * Removes any members 00278 */ 00279 ~LinkedList() { 00280 // free any memory that is on the heap 00281 while(remove(1) != NULL); 00282 } 00283 00284 /** Add a member to the begining of the list 00285 * @param data - Some data type that is added to the list 00286 * @return The member that was just inserted (NULL if empty) 00287 */ 00288 node<T> *push(T *data) 00289 { 00290 node<T> *new_node = new node<T>[1]; 00291 // make sure the new object was allocated 00292 if (0 == new_node) 00293 { 00294 error("Memory allocation failed\n"); 00295 } 00296 // update the next item in the list to the current head 00297 new_node->next = _head; 00298 // store the address to the linked datatype 00299 new_node->data = data; 00300 _head = new_node; 00301 00302 return _head; 00303 } 00304 00305 /** Add a member to some position based on sort condition. 00306 * The list will be iterated from _head to end and the moment inserted 00307 * data is NOT smaller than current node's data, then 00308 * data will be inserted in front of current node. 00309 * This will preserve ascending order of data. 00310 * @param data - some data type that is added to the list 00311 * @param isBigger - comparator function returns true if data1 is bigger 00312 * than data2 and false otherwise. 00313 * If data1 equals data2, then ">" comparision 00314 * will result in LIFO order. Using ">=" operator in the function 00315 * results in "FIFO" order and thus it preserves order in which items 00316 * were added to the list. 00317 * 00318 * If isBigger function is implemented with data1 < data2, then 00319 * result insert will be in descending order. If data1 equals data2, then 00320 * LIFO order is established. 00321 * If data1 <= data2, then FIFO order is preserved when data1 equals data2. 00322 * 00323 * @return The member that was just inserted (NULL if not inserted). 00324 */ 00325 node<T> *insertOrdered(T *data, bool (isBigger)(T* data1, T *data2)) 00326 { 00327 node<T> *new_node = new node<T> [1]; 00328 // make sure the new object was allocated 00329 if (0 == new_node) 00330 { 00331 error("Memory allocation failed\n"); 00332 } 00333 // store the address to the linked datatype 00334 new_node->data = data; 00335 // clear the next pointer 00336 new_node->next = 0; 00337 // check for an empty list 00338 if (0 == _head) 00339 { 00340 _head = new_node; 00341 DBG("[insertAsc] set as head\n"); 00342 return new_node; 00343 } 00344 00345 node<T> *current = _head; 00346 node<T> *prev = 0; 00347 // move to the item we want to insert 00348 while (isBigger(data, current->data )) 00349 { 00350 // while(true) execute the following 00351 // data being inserted is smaller than current->data 00352 if (0 == current->next ) { 00353 // there is no more data 00354 DBG("[insertAsc] insert at end\n"); 00355 current->next = new_node; 00356 return new_node; 00357 } 00358 prev = current; 00359 current = current->next ; 00360 } 00361 if (0 == prev) { 00362 DBG("[insertAsc] insert at start\n"); 00363 new_node->next = _head; 00364 _head = new_node; 00365 return new_node; 00366 } 00367 DBG("[insertAsc] insert inside\n"); 00368 new_node->next = current; 00369 prev->next = new_node; 00370 return new_node; 00371 } 00372 00373 /** Add a member to the end of the list 00374 * @param data - Some data type that is added to the list 00375 * @return The member that was just inserted (NULL if empty) 00376 */ 00377 node<T> *append(T *data) 00378 { 00379 node<T> *current = _head; 00380 node<T> *new_node = new node<T> [1]; 00381 // make sure the new object was allocated 00382 if (0 == new_node) 00383 { 00384 error("Memory allocation failed\n"); 00385 } 00386 // store the address to the linked datatype 00387 new_node->data = data; 00388 // clear the next pointer 00389 new_node->next = 0; 00390 // check for an empty list 00391 if (0 == current) 00392 { 00393 _head = new_node; 00394 return _head; 00395 } 00396 else 00397 { 00398 // look for the end of the list 00399 while (current->next != 0) 00400 { 00401 current = current->next ; 00402 } 00403 // and then add the new item to the list 00404 current->next = new_node; 00405 } 00406 00407 return current->next ; 00408 } 00409 00410 /** Remove a member from the list 00411 * @param loc - The location of the member to remove 00412 * @return The head of the list 00413 */ 00414 node<T> *remove(uint32_t loc) 00415 { 00416 node<T> *current = _head; 00417 node<T> *prev = 0; 00418 // make sure we have an item to remove 00419 if ((loc <= length()) && (loc > 0)) 00420 { 00421 // move to the item we want to delete 00422 if (1 == loc) 00423 { 00424 _head = current->next ; 00425 delete [] current; 00426 } 00427 else 00428 { 00429 for (uint32_t i=2; i<=loc; ++i) 00430 { 00431 prev = current; 00432 current = current->next ; 00433 } 00434 // store the item + 1 to replace what we are deleting 00435 prev->next = current->next ; 00436 delete [] current; 00437 } 00438 } 00439 00440 return _head; 00441 } 00442 00443 /** Get access to a member from the list 00444 * @param loc - The location of the member to access 00445 * @return The member that was just requested (NULL if empty or out of bounds) 00446 */ 00447 node<T> *pop(uint32_t loc) 00448 { 00449 node<T> *current = _head; 00450 // make sure we have something in the location 00451 if ((loc > length()) || (loc == 0)) 00452 { 00453 return 0; 00454 } 00455 // and if so jump down the list 00456 for (uint32_t i=2; i<=loc; ++i) 00457 { 00458 current = current->next ; 00459 } 00460 00461 return current; 00462 } 00463 00464 node<T> *pop(T* data, bool (isEqual)(T* data1, T* data2)) 00465 { 00466 DBG("..pop started\n"); 00467 if (_head == NULL) { 00468 DBG(".._head is NULL\n"); 00469 return NULL; 00470 } 00471 node<T> *current = _head; 00472 // make sure we have something in the location 00473 // and if so jump down the list 00474 while(!isEqual(current->data , data)) { 00475 DBG("..next current\n"); 00476 if (current->next == NULL) { 00477 DBG("..next is NULL; returning NULL\n"); 00478 return NULL; 00479 } 00480 current = current->next ; 00481 } 00482 DBG("..found\n"); 00483 return current; 00484 } 00485 00486 /** Get the length of the list 00487 * @return The number of members in the list 00488 */ 00489 uint32_t length(void) 00490 { 00491 int32_t count = 0; 00492 node<T> *current = _head; 00493 //loop until the end of the list is found 00494 while (current != 0) 00495 { 00496 ++count; 00497 current = current->next ; 00498 } 00499 00500 return count; 00501 } 00502 00503 }; 00504 00505 #endif /* LINKEDLIST_H_ */
Generated on Wed Jul 13 2022 14:39:12 by
1.7.2
