单链表

简介: /* linkedlist.h */ #ifndef LINKEDLIST_H #define LINKEDLIST_H typedef struct node *link; struct node { unsigned char item; link next;}; link make_node(unsigned char item);void
/* linkedlist.h */
#ifndef LINKEDLIST_H
#define LINKEDLIST_H

typedef struct node *link;
struct node { 
         unsigned char item; 
link next;};

link make_node(unsigned char item);void free_node(link p);
link search(unsigned char key);
void insert(link p);
link delete(link p);
void traverse(void (*visit)(link));
void destroy(void);
void push(link p);
link pop(void);

#endif

/* linkedlist.c */

#include <stdlib.h>
#include "linkedlist.h"

static link head = NULL;   //初始化为空链表

link make_node(unsigned char item){ 
	link p = malloc(sizeof *p);
	p->item = item;
	p->next = NULL;
	return p;}
void free_node(link p)
{ 
	free(p);
}
link search(unsigned char key)
{ 
	link p;
	for (p = head; p; p = p->next)      ///遍历链表,活动节点先指向head,然后判断,然后next,最后如果p为NULL,则遍历结束!
		if (p->item == key) 
		return p; 
	return NULL;}

void insert(link p)
{ 
	p->next = head; 
	head = p;
}

link delete(link p)
{ 
	link prev; 
	if (p == head) { 
		head = p->next; 
		return p; }
	for (prev = head; prev; prev = prev->next)
		if (prev->next == p) 
		{ prev->next = p->next; 
		return p; } 
	return NULL;
}

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

void push(link p)
{ 
	insert(p);
}

link pop(void)
{ 
	if (head == NULL) 
	return NULL; 
	else 
	return delete(head);
}


 

/* main.c */

#include <stdio.h>
#include "linkedlist.h"

void print_item(link p)
{ 
	printf("%d\n", p->item); 
}

int main(void)
{ 
	link p = make_node(10);
	insert(p); 
	p = make_node(5); 
	insert(p); 
	p = make_node(90);
	insert(p); 
	p = search(5); 
	delete(p); 
	free_node(p); 
	traverse(print_item); 
	destroy(); 
	p = make_node(100); 
	push(p); 
	p = make_node(200); 
	push(p); 
	p = make_node(250); 
	push(p); 
	while (p = pop()) 
	{ 
		print_item(p); 
		free_node(p); }
	return 0;
}


 

删除一个节点的图示:

从上图可以看出,要摘除一个节点需要首先找到它的前趋然后才能做摘除操作,而在单链表中通过某个节点只能找到它的后继而不能找到它的前趋,所以删除操作要麻烦一些,需要从第一个节点开始依次查找要摘除的节点的前趋。delete操作也要处理一种特殊情况,如果要摘除的节点是链表的第一个节点,它是没有前趋的,这种情况要用特殊的代码处理,而不能和一般情况用同样的代码处理。这样很不爽,能不能把这种特殊情况转化为一般情况呢?可以把delete函数改成这样:

link delete(link p)
{ 
	link *pnext; 
	for (pnext = &head; *pnext; pnext = &(*pnext)->next) 
		if (*pnext == p) { 
		*pnext = p->next; 
		return p; } 
	return NULL;
}

 

 

目录
相关文章
|
存储
【单链表】
【单链表】
73 0
|
4月前
|
存储
单链表专题(冲冲冲)(下)
单链表专题(冲冲冲)(下)
57 0
|
4月前
|
存储
单链表专题(冲冲冲)(上)
单链表专题(冲冲冲)(上)
55 0
|
8月前
|
存储 算法
单链表的应用
单链表的应用
50 6
|
8月前
|
存储
单链表专题
单链表专题
46 4
|
9月前
|
存储 编译器
单链表与双链表实现
单链表与双链表实现
|
8月前
|
存储
单链表的实现
单链表的实现
32 0
|
9月前
|
搜索推荐
了解单链表
了解单链表
57 0
|
9月前
|
存储 C语言
单链表详解
单链表详解
134 0
|
9月前
|
存储 缓存
详解单链表
详解单链表
81 0