双向链表简介。
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
双向链表更快速的查找与遍历整个链表。所以我们很少用单链表了。
<pre lang="c" escaped="true">
/* doublelinkedlist.h */
#ifndef DOUBLELINKEDLIST_H
#define DOUBLELINKEDLIST_H
typedef struct node *link;
struct node
{
unsigned char elem;
link pre, next;
};
link make_node(unsigned char elem);
void free_node(link p);
link search(unsigned char elem);
void insert(link p);
void delete(link p);
void traverse(void (*visit)(link));
void destroy(void);
void enqueue(link p);
link dequeue(void);
#endif
</pre>
<pre lang="c" escaped="true">
/* doublelinkedlist.c */
#include <stdlib.h>
#include "doublelinkedlist.h"
struct node tailsentinel;
struct node headsentinel = {0, NULL, &tailsentinel};
struct node tailsentinel = {0, &headsentinel, NULL};
static link head = &headsentinel;
static link tail = &tailsentinel;
link make_node(unsigned char elem)
{
link p = malloc(sizeof(*p));
p->elem = elem;
p->pre = p->next = NULL;
return p;
}
void free_node(link p)
{
free(p);
}
link search(unsigned char elem)
{
link p;
for (p = head->next; p != tail; p = p->next)
if (p->elem == elem)
return p;
return NULL;
}
void insert(link p)
{
p->next = head->next;
head->next->pre = p;
head->next = p;
p->pre = head;
}
void delete(link p)
{
p->pre->next = p->next;
p->next->pre = p->pre;
}
void traverse(void (*visit)(link))
{
link p;
for (p = head->next; p != tail; p = p->next)
visit(p);
}
void destroy(void)
{
link q, p = head->next;
head->next = tail;
tail->pre = head;
while (p != tail)
{
q = p;
p = p->next;
free_node(q);
}
}
void enqueue(link p)
{
insert(p);
}
link dequeue(void)
{
if (tail->pre == head)
return NULL;
else
{
link p = tail->pre;
delete(p);
return p;
}
}
</pre>
<pre lang="c" escaped="true">
#include <stdio.h>
#include "doublelinkedlist.h"
void print_elem(link p)
{
printf("%d
", p->elem);
}
int main(void)
{
link p;
insert(make_node(10));
insert(make_node(5));
insert(make_node(90));
p = search(5);
delete(p);
free_node(p);
traverse(print_elem);
destroy();
enqueue(make_node(100));
enqueue(make_node(200));
enqueue(make_node(250));
while (p = dequeue())
{
print_elem(p);
free_node(p);
}
return 0;
}
</pre>