单向链表
单链表有一个头节点head,指向链表在内存的首地址。链表中的每一个节点的数据类型为结构体类型,节点有两个成员:整型成员(实际需要保存的数据)和指向下一个结构体类型节点的指针即下一个节点的地址(事实上,此单链表是用于存放整型数据的动态数组)。链表按此结构对各节点的访问需从链表的头找起,后续节点的地址由当前节点给出。无论在表中访问那一个节点,都需要从链表的头开始,顺序向后查找。链表的尾节点由于无后续节点,其指针域为空,写作为NULL。
<a href="http://www.emacsvi.com/wp-content/uploads/2015/10/linkedlist.bmp"><img src="http://www.emacsvi.com/wp-content/uploads/2015/10/linkedlist.bmp" alt="linkedlist" width="600" height="130" class="alignnone size-full wp-image-274" /></a>
<pre lang="c" escaped="true">
/* linkedlist.h */
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
typedef struct node *link;
struct node
{
unsigned char elem;
link 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 push(link p);
link pop(void);
#endif
</pre>
<pre lang="c" escaped="true">
#include <stdlib.h>
#include "linkedlist.h"
static link head=NULL;
link make_node(unsigned char elem)
{
link p = malloc(sizeof(*p));
p->elem = elem;
p->next = NULL;
return p;
}
void free_node(link p)
{
free(p);
}
link search(unsigned char elem)
{
link p;
for (p = head; p; p = p->next)
if (elem == p->elem)
return p;
return NULL;
}
void insert(link p)
{
p->next = head;
head = p;
}
void delete(link p)
{
link pre;
if (head == p)
{
head = p->next;
return;
}
for (pre = head; pre; pre = pre->next)
if (pre->next == p)
{
pre->next = p->next;
return;
}
}
/* 没有看太明白
void delete(link p)
{
link *pnext;
for (pnext = &head; *pnext; pnext = &(*pnext)->next)
if (*pnext == p)
{
*pnext = p->next;
return;
}
}
*/
void traverse(void (*visit)(link))
{
link p;
for (p = head; p; p = p->next)
visit(p);
}
void destroy(void)
{
link q, p=head;
head = NULL;
while (p)
{
q = p;
p = p->next;
free_node(q);
}
}
void push(link p)
{
insert(p);
}
link pop(void)
{
if (NULL == head)
return NULL;
else
{
link p = head;
head = head->next;
return p;
}
}
</pre>
<pre lang="c" escaped="true">
#include <stdio.h>
#include "linkedlist.h"
void print_elem(link p)
{
printf("%d\n", 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();
push(make_node(100));
push(make_node(200));
push(make_node(250));
while (p = pop())
{
print_elem(p);
free_node(p);
}
return 0;
}
</pre>