(3) double-linked list: insque remque


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);
       }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值