1.
/**
* The insque and remque subroutines manipulate queues built from double-linked lists.
* Each element in the queue must be in the form of a qelem structure. The next and
* prev elements of that structure must point to the elements in the queue immediately
* before and after the element to be inserted or deleted.
*
* The insque subroutine inserts the element pointed to by the Element parameter into
* a queue immediately after the element pointed to by the Pred parameter.
* The remque subroutine removes the element defined by the Element parameter from a queue.
*
* #include <search.h>
* Inserts or removes an element in a queue.
* void insque(void *elem, void *prev);
* void remque(void *elem);
*
struct qelem {
struct qelem *q_forw;
struct qelem *q_back;
};
void insque (struct qelem *elem, struct qelem *pred)
{
elem -> q_forw = pred -> q_forw;
pred -> q_forw -> q_back = elem;
elem -> q_back = pred;
pred -> q_forw = elem;
}
void remque (struct qelem *elem)
{
elem -> q_forw -> q_back = elem -> q_back;
elem -> q_back -> q_forw = elem -> q_forw;
}
*/
#ifndef _GNU_SOURCE
struct qelem {
struct qelem *q_forw;
struct qelem *q_back;
char *element;
};
#endif
#include <search.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void *xmalloc(unsigned n) {
void *p;
p = malloc(n);
if (p) return p;
fprintf(stderr, "malloc failure, insufficient memory.\n");
exit(1);
}
struct qelem *create_head(){
struct qelem *head = (struct qelem *)xmalloc(sizeof(struct qelem));
head->q_forw = head;
head->q_back = head;
return head;
}
int main(int argc, char **argv){
struct qelem *head = create_head();//head's element is blank
struct qelem *prev = head;
struct qelem *tmp;
//insque, actually insert the first element into ahead of head
int i;
for(i = 1; i < argc; i++){
struct qelem *node = (struct qelem *)xmalloc(sizeof(struct qelem));
node->element = argv[i];
insque(node, prev);
prev = node;
}
//traversing the list
tmp = prev;
puts("traversing the list:");
while(tmp != head){
puts(tmp->element);
tmp = tmp->q_back;
}
//remque the first element after head
puts("after remque, go through:");
remque(head->q_forw);
tmp = head->q_forw;
while(tmp != head){
puts(tmp->element);
tmp = tmp->q_forw;
}
return 0;
}
2
$ ./a.out -c a b c
Traversing completed list:
a
b
c
That was a circular list
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <search.h>
struct element {
struct element *forward;
struct element *backward;
char *name;
};
static struct element *
new_element(void)
{
struct element *e;
e = malloc(sizeof(struct element));
if (e == NULL) {
fprintf(stderr, "malloc() failed\n");
exit(EXIT_FAILURE);
}
return e;
}
int
main(int argc, char *argv[])
{
struct element *first, *elem, *prev;
int circular, opt, errfnd;
/* The "-c" command-line option can be used to specify that the
list is circular */
errfnd = 0;
circular = 0;
while ((opt = getopt(argc, argv, "c")) != -1) {
switch (opt) {
case 'c':
circular = 1;
break;
default:
errfnd = 1;
break;
}
}
if (errfnd || optind >= argc) {
fprintf(stderr, "Usage: %s [-c] string...\n", argv[0]);
exit(EXIT_FAILURE);
}
/* Create first element and place it in the linked list */
elem = new_element();
first = elem;
elem->name = argv[optind];
if (circular) {
elem->forward = elem;
elem->backward = elem;
insque(elem, elem);
} else {
insque(elem, NULL);
}
/* Add remaining command-line arguments as list elements */
while (++optind < argc) {
prev = elem;
elem = new_element();
elem->name = argv[optind];
insque(elem, prev);
}
/* Traverse the list from the start, printing element names */
printf("Traversing completed list:\n");
elem = first;
do {
printf(" %s\n", elem->name);
elem = elem->forward;
} while (elem != NULL && elem != first);
if (elem == first)
printf("That was a circular list\n");
exit(EXIT_SUCCESS);
}