#include #include typedef struct _List { int val; struct _List * next; } List; List * LNewFromInt(int x) { List * ans = (List*)malloc(sizeof(List)); ans->val = x; ans->next = NULL; return ans; } List * LNewFromArray(int len, int* p) { List * ans = NULL; int i; for(i=len-1; i >= 0; --i) { List * next = LNewFromInt(p[i]); next->next = ans; ans = next; } return ans; } List * LCopy(List *lst) { if (lst == NULL) return NULL; List * ans = LNewFromInt(lst->val); List * tmp = ans; while (lst->next != NULL) { lst = lst->next; tmp->next = LNewFromInt(lst->val); tmp = tmp->next; } return ans; } // frees the whole list; better not use any other pointers // to any list elements void LFree(List * lst) { while(lst != NULL) { List *next = lst->next; // must precede next statement free(lst); lst = next; } } void LPrint(List * lst) { printf("\n["); while(lst != NULL) { printf(" %d ", lst->val); lst = lst->next; } printf("]\n"); } int LMember(List *lst, int x) { for(; lst != NULL; lst = lst->next) if(lst->val == x) return 1; return 0; } int LLengthRecursive(List *lst) { if(lst==NULL) return 0; return 1 + LLengthRecursive(lst->next); } int LLength(List *lst) { int ans = 0; while(lst != NULL) { ++ans; lst = lst->next; } return ans; } // change lst1; copy lst2 List* LAppend(List*lst1, List*lst2) { if(lst1==NULL) return NULL; List* ans = lst1; while(lst1->next != NULL) lst1 = lst1->next; lst1->next = LCopy(lst2); return ans; } // change lst1; link to lst2 List* LAppendShare(List*lst1, List*lst2) { if(lst1==NULL) return NULL; List* ans = lst1; while(lst1->next != NULL) lst1 = lst1->next; lst1->next = lst2; return ans; } // copy lst1 and lst2 List* LNewFromLists(List*lst1, List*lst2) { lst1 = LCopy(lst1); lst2 = LCopy(lst2); if(lst1==NULL) return lst2; List* ans = lst1; while(lst1->next != NULL) lst1 = lst1->next; lst1->next = lst2; return ans; } void test() { int arr1[5] = { 2, 4, 6, 8, 10}; int arr2[3] = { 1, 2, 3}; int arr3[4] = {20, 0, 0, 0}; List *lst1 = LNewFromArray(5,arr1); List *lst2 = LNewFromArray(3,arr2); List *lst3 = LNewFromArray(4,arr3); LPrint(lst1); LPrint(lst2); LPrint(lst3); LPrint(LNewFromLists(lst1,lst2)); // space leak! LPrint(lst1); LPrint(lst2); LAppendShare(lst1,lst2); LPrint(lst1); LPrint(lst2); LAppendShare(lst1,lst1); // An awfully bad idea! Why? //LPrint(lst1); // space-leak: Cannot LFree lst1 (circular) // Cannot LFree lst2 (now part of lst1) // Can LFree lst3 } int main(int argc, char**argv) { test(); return 0; }