$ cat new.c #include #include #include #include #define pp(x) printf("%s = %p\n", #x, x); #define pi(x) printf("%s = %d\n", #x, x); #define pc(x) printf("%s = %c\n", #x, x); #define psize_t(x) printf("%s = %zu\n", #x, x); // A C program to demonstrate linked list based implementation of queue // A linked list (LL) node to store a queue entry int index_start = -1; int ref_start = 0; int global_indent = 0; #define node_init(t, i, r, nc, n) t->index = i; t->ref = r; t->next_count = nc; t->next = n; t->level = global_indent; #define STORE_NORMAL 1 #define STORE_EMPTY 2 #define NODE_TYPE_NORMAL 1 #define NODE_TYPE_BRANCH_START 2 #define NODE_TYPE_BRANCH_END 3 #define NODE_TYPE_BRANCH_CHOICE_START 4 #define NODE_TYPE_BRANCH_CHOICE_END 5 #define POINTER_LIST_TYPE int POINTER_LIST_TYPE ** ptr_list = NULL; ssize_t ptr_list_size = 0; int last_ref = 0; int ptr_add(POINTER_LIST_TYPE * ptr) { if (!ptr) return -1; POINTER_LIST_TYPE ** pl; if (!ptr_list) { ptr_list = malloc(sizeof(ptr_list)*2); } else if (ptr_list) { ptr_list = realloc(ptr_list, sizeof(ptr_list)*(ptr_list_size+1)); } ptr_list[ptr_list_size] = ptr; ptr_list_size++; ptr_list[ptr_list_size] = NULL; // psize_t(ptr_list_size); return 0; } int ptr_print(void) { if (!ptr_list) return -1; POINTER_LIST_TYPE ** pl; for (pl = ptr_list; *pl; pl++) pp(*pl); return 0; } int ptr_set(POINTER_LIST_TYPE data) { if (!ptr_list) return -1; POINTER_LIST_TYPE ** pl; for (pl = ptr_list; *pl; pl++) **pl = data; return 0; } int ptr_free(void) { if (!ptr_list) return -1; POINTER_LIST_TYPE ** pl; for (pl = ptr_list; *pl; pl++) *pl = NULL; free(ptr_list); ptr_list = NULL; ptr_list_size = 0; return 0; } struct QNode { int level; int index; int ref; int next_count; int type; struct QNode **next; }; // The queue, front stores the front node of LL and rear stores ths // last node of LL struct Queue { struct QNode *front, *rear; }; // A utility function to create a new linked list node. struct QNode* newNode(int type) { struct QNode *temp = (struct QNode*)malloc(sizeof(struct QNode)); if (type == STORE_NORMAL) { node_init(temp, index_start++, ref_start++, 0, NULL); } else if (type == STORE_EMPTY) { node_init(temp, 0, 0, 0, NULL); } return temp; } // A utility function to create an empty queue struct Queue *createQueue() { struct Queue *q = (struct Queue*)malloc(sizeof(struct Queue)); q->front = q->rear = NULL; return q; } void store_asm(struct Queue *q, int type) { // Create a new LL node int t = 0; if (type == NODE_TYPE_NORMAL) t = STORE_NORMAL; else if ( type == NODE_TYPE_BRANCH_START || type == NODE_TYPE_BRANCH_END || type == NODE_TYPE_BRANCH_CHOICE_START || type == NODE_TYPE_BRANCH_CHOICE_END ) t = STORE_EMPTY; struct QNode *temp = newNode(t); temp->type = type; // If queue is empty, then new node is front and rear both if (q->rear == NULL) { q->front = q->rear = temp; if (!q->rear->next) { q->rear->next_count = 1; q->rear->next = malloc(sizeof(struct QNode)*q->rear->next_count); } else { q->rear->next_count++; q->rear->next = realloc(q->rear->next, sizeof(struct QNode)*q->rear->next_count); } return; } if (type == NODE_TYPE_BRANCH_CHOICE_END) { // pp(&q->rear->ref) last_ref = q->rear->ref; ptr_add(&q->rear->ref); } else if(type == NODE_TYPE_BRANCH_END) { // pi(last_ref); ptr_set(last_ref); ptr_free(); } // Add the new node at the end of queue and change rear q->rear->next[q->rear->next_count-1] = temp; q->rear = temp; if (!q->rear->next) { q->rear->next_count = 1; q->rear->next = malloc(sizeof(struct QNode)*q->rear->next_count); } else { q->rear->next_count++; q->rear->next = realloc(q->rear->next, sizeof(struct QNode)*q->rear->next_count); } } void add(struct Queue **q) { if (!(*q)) (*q) = createQueue(); store_asm((*q), NODE_TYPE_NORMAL); } #define add_indent(indent) { int i = 0; for (; i < indent; i++) printf(" "); } struct Queue * list = NULL; void print(struct QNode * p, int indent) { int indentation = 0; while(p) { indentation = p->level; add_indent(indentation); if (p->type == NODE_TYPE_BRANCH_START) { add_indent(indentation); printf("branch start\n"); } else if (p->type == NODE_TYPE_BRANCH_END) { add_indent(indentation); printf("branch end\n"); } else if (p->type == NODE_TYPE_BRANCH_CHOICE_START) { add_indent(indentation); printf("branch choice start\n"); } else if (p->type == NODE_TYPE_BRANCH_CHOICE_END) { add_indent(indentation); printf("branch choice end\n"); } else if (p->type == NODE_TYPE_NORMAL) { add_indent(indentation); printf("%d -> %d\n", p->index, p->ref); if (p->next_count > 1) print(p->next[1], indent+1); } if (p->next) p = p->next[0]; else p = NULL; } add_indent(indentation); puts("NULL"); } void add_branch(struct Queue **q) { if (!(*q)) (*q) = createQueue(); store_asm((*q), NODE_TYPE_BRANCH_START); global_indent++; } void end_branch(struct Queue **q) { global_indent--; if (!(*q)) (*q) = createQueue(); store_asm((*q), NODE_TYPE_BRANCH_END); } void add_branch_choice(struct Queue **q) { if (!(*q)) (*q) = createQueue(); store_asm((*q), NODE_TYPE_BRANCH_CHOICE_START); global_indent++; } void end_branch_choice(struct Queue **q) { global_indent--; if (!(*q)) (*q) = createQueue(); store_asm((*q), NODE_TYPE_BRANCH_CHOICE_END); } int main(void) { index_start = 0; ref_start = 1; add(&list); add_branch(&list); add_branch_choice(&list); add(&list); add(&list); end_branch_choice(&list); add_branch_choice(&list); add(&list); add(&list); end_branch_choice(&list); end_branch(&list); add(&list); print(list->front, 0); ptr_print(); return 0; } $ gcc new.c -o new $ ./new 0 -> 1 branch start branch choice start 1 -> 2 2 -> 5 branch choice end branch choice start 3 -> 4 4 -> 5 branch choice end branch end 5 -> 6 NULL