双向线性链表的实现

头文件“ls.h”

/* 双向线性链表 */
#ifndef _LS_H
#define _LS_H
#include <sys/types.h>

/* 节点 */
typedef struct ListNode {
	int              data; /* 数据 */
	struct ListNode* prev; /* 前指针 */
	struct ListNode* next; /* 后指针 */
}	LIST_NODE;

/* 链表 */
typedef struct List {
	LIST_NODE* head; /* 头指针 */
	LIST_NODE* tail; /* 尾指针 */
	/*考虑用户需求,提供迭代接口*/
	LIST_NODE* frwd;//正向迭代指针,指向链表中任意指针,正向移动
	LIST_NODE* bkwd;//反向迭代指针
}	LIST;

/* 初始化为空链表 */
void list_init (LIST* list);

/* 释放剩余节点并恢复到初始状态 */
void list_deinit (LIST* list);

/* 判断是否空 */
int list_empty (LIST* list);

/* 追加 */
void list_append (LIST* list, int data);

/* 前插 */
int list_insert (LIST* list, size_t pos, int data);

/* 随机访问 */
int* list_at (LIST* list, size_t pos);//int*是返回位置,为了方便用户读并进行后续修改,删除等操作

/* 删除 */
int list_erase (LIST* list, size_t pos);

/* 删除所有匹配数据 */
void list_remove (LIST* list, int data);

/* 清空 */
void list_clear (LIST* list);

/* 数量 */
size_t list_size (LIST* list);

//双向正向迭代器
/*开始正向迭代——随机遍历(让用户可以随机迭代)*/
void list_begin (LIST* list);

/* 向后正向迭代 */
int* list_next (LIST* list);

/* 向前正向迭代 */
int* list_prev (LIST* list);

/* 获取正向迭代当前值 */
int* list_current (LIST* list);

/* 判断正向迭代是否终止 */
int list_end (LIST* list);


//反向迭代器
/* 开始反向迭代 */
void list_rbegin (LIST* list);

/* 向后反向迭代 */
int* list_rnext (LIST* list);

/* 向前反向迭代 */
int* list_rprev (LIST* list);

/* 获取反向迭代当前值 */
int* list_rcurrent (LIST* list);

/* 判断反向迭代是否终止 */
int list_rend (LIST* list);

#endif /* _LS_H */

函数具体实现过程"ls.c"

/* 双向线性链表 */
#include <stdlib.h>
#include "ls.h"
/* 创建节点 */
static LIST_NODE* create_node (int data,
	LIST_NODE* prev, LIST_NODE* next) {
	LIST_NODE* node = malloc (sizeof (LIST_NODE));
	node->data = data;
	node->prev = prev;
	node->next = next;
	return node;
}

/* 销毁节点 */
static LIST_NODE* destroy_node (LIST_NODE* node,
	LIST_NODE** prev) {
	LIST_NODE* next = node->next;
	if (prev)
		*prev = node->prev;
	free (node);
	return next;
}

/* 初始化为空链表 */
void list_init (LIST* list) {
	list->head = NULL;
	list->tail = NULL;
}

/* 释放剩余节点并恢复到初始状态 */
void list_deinit (LIST* list) {
	while (list->head)
		list->head = destroy_node (list->head,NULL);
	list->tail = NULL;
}

/* 判断是否空 */
int list_empty (LIST* list) {
	return ! list->head && ! list->tail;
}
/* 追加 */
void list_append (LIST* list, int data) {
	list->tail = create_node (data,list->tail,NULL);
	if (list->tail->prev)
		list->tail->prev->next = list->tail;
	else
		list->head = list->tail;
}

/* 前插 */
int list_insert (LIST* list, size_t pos, int data) {
	LIST_NODE* find = NULL;
	for (find = list->head; find; find = find->next)
		if (! pos--) {
			LIST_NODE* node = create_node (data,
				find->prev, find);
			if (node->prev)
				node->prev->next = node;
			else
				list->head = node;
			node->next->prev = node;
			return 1;
		}
	return 0; //插入失败
}

/* 随机访问 */
int* list_at (LIST* list, size_t pos) {
	LIST_NODE* find = NULL;
	for (find = list->head; find; find = find->next)
		if (! pos--)
			return &find->data;
	return NULL;
}
/* 删除 */
int list_erase (LIST* list, size_t pos) {
	LIST_NODE* find = NULL;
	for (find = list->head; find; find = find->next)
		if (! pos--) {
			LIST_NODE* prev = NULL;
			LIST_NODE* next = destroy_node (find,
				&prev);
			if (prev)
				prev->next = next;
			else
				list->head = next;
			if (next)
				next->prev = prev;
			else
				list->tail = prev;
			return 1;
		}
	return 0;
}

/* 删除所有匹配数据 */
void list_remove (LIST* list, int data) {
	LIST_NODE* find = NULL, *next = NULL;
	for (find = list->head; find; find = next) {
		next = find->next;
		if (find->data == data) {
			LIST_NODE* prev = NULL;
			LIST_NODE* next = destroy_node (find,
				&prev);
			if (prev)
				prev->next = next;
			else
				list->head = next;
			if (next)
				next->prev = prev;
			else
				list->tail = prev;
		}
	}
}

/* 清空 */
void list_clear (LIST* list) {
	list_deinit (list);
}

/* 数量 */
size_t list_size (LIST* list) {
	size_t size = 0;
	LIST_NODE* node = NULL;
	for (node = list->head; node; node = node->next)
		++size;
	return size;
}

/* 开始正向迭代 */
void list_begin (LIST* list) {
	list->frwd = list->head;
}

/* 向后正向迭代 */
int* list_next (LIST* list) {
	int* data = &list->frwd->data;
	list->frwd = list->frwd->next;
	return data;
}

/* 向前正向迭代 */
int* list_prev (LIST* list) {
	int* data = &list->frwd->data;
	list->frwd = list->frwd->prev;
	return data;
}

/* 获取正向迭代当前值 */
int* list_current (LIST* list) {
	return &list->frwd->data;
}
/* 判断正向迭代是否终止 */
int list_end (LIST* list) {
	return ! list->frwd;
}
/* 开始反向迭代 ,与正向迭代的反向迭代方向相反*/ 
void list_rbegin (LIST* list) {
	list->bkwd = list->tail;
}
/* 向后反向迭代 */
int* list_rnext (LIST* list) {
	int* data = &list->bkwd->data;
	list->bkwd = list->bkwd->prev;
	return data;
}
/* 向前反向迭代 */
int* list_rprev (LIST* list) {
	int* data = &list->bkwd->data;
	list->bkwd = list->bkwd->next;
	return data;
}

/* 获取反向迭代当前值 */
int* list_rcurrent (LIST* list) {
	return &list->bkwd->data;
}
/* 判断反向迭代是否终止 */
int list_rend (LIST* list) {
	return ! list->bkwd;
}

测试用例"ls_test.c"

/* 双向线性链表 */
#include <stdio.h>
#include "ls.h"
/* 测试用例 */
int main (void) {
	LIST list;
	list_init (&list);
	list_append (&list, 10);
	list_append (&list, 30);
	list_append (&list, 50);
	list_insert (&list, 1, 20);
	list_insert (&list, 3, 40);
	for (list_begin (&list); ! list_end (&list);
		list_next (&list))
		printf ("%d ", ++*list_current (&list));
	printf ("\n");
	list_append (&list, 41);
	list_append (&list, 41);
	list_begin (&list);
	while (! list_end (&list))
		printf ("%d ", *list_next (&list));
	printf ("\n");
	list_erase (&list, 1);
	list_remove (&list, 41);
	list_rbegin (&list);
	while (! list_rend (&list))
		printf ("%d ", *list_rnext (&list));
	printf ("\n");
	size_t pos, size = list_size (&list);
	for (pos = 0; pos < size; ++pos)
		printf ("%d ", --*list_at (&list, pos));
	printf ("\n");
	list_clear (&list);
	printf ("%d, %d\n", list_empty (&list),
		list_size (&list));
	list_deinit (&list);
	return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值