Warm-up assignment 2: A linked list

In this assignment you'll implement a linked list data structure supporting all standard operations: initialize, insert at head, delete at tail, insert in order, delete an arbitrary node, get size, etc.

Startup code is provided here. It contains 3 files:

The header file starts by defining the node for the list, and the list (this would be a good time to review typedefs and structures in C):
typedef struct node_t {
  int value;
  struct node_t *next;
  struct node_t *prev;
} Node;

typedef struct llist_t {
  Node* head;
  Node* tail;
  int size;  //number of elements in the list 
} LList; 
Note that it's a doubly linked list that holds its size, head and tail. The signatures of the functions operating on linked lists are listed below. Note that we are essentially thinking of a linked-list as a class, even though C is not an OO language --- the idea of encapsulations and modularization are the same.
/* create and return an empty list */
LList* LList_init();

/* return size (number of elements)  of list */
int LList_size(LList* l);

/* print all values in the list in order form head to tail  */
void LList_print(LList * l);

/* return the head of the list */
Node *LList_head(LList *l);

/* return the tail of the list */
Node *LList_tail(LList *l);

/* create a new node with value=key and insert it in the  list at the head */
void LList_insert_at_head(LList *l, int key);

/* This operation assumes the list is sorted in increasing order of
the values.  It create a new node with value=key and insert it in the
list in the right place (ie before the first node that's larger than
the key) */
void LList_insert_in_order(LList *l, int key);

/* this function checks if the list is sorted in incresing order;
   return 1 if list is sorted, 0 otherwise*/
int LList_is_sorted(LList *l);

/* delete the node at the tail from the list and return it. It does
   NOT free the node.  */ 
Node* LList_delete_at_tail(LList *l);

/* assume n is pointing to a node in l; delete it from the list (link
   its predeccor to it's sucessor). It does NOT free the node.  */
void  LList_delete(LList* l, Node* n);

/* delete and free all nodes in the list */
void LList_delete_all(LList* l);

/* delete and free all nodes in the list and the list  */
void LList_free(LList* l);
The file llist.c is essentially empty and needs to be filled out by you.

I have also provided a Makefile. Spend some time reading the Makefile and understand the dependencies (I'll expect you'll create Makefiles on your own for the next assignments).

To test your implementation, you'll need to run llistTester and check that you get the expected results. The code that I provided compiles as is, and gives an assert error when run.

A few more things: