双向链表(五)

2014-11-24 11:12:16 · 作者: · 浏览: 11
entry_safe_continue(pos, n, head, member) \ for (pos = list_entry(pos->member.next, typeof(*pos), member), \ n = list_entry(pos->member.next, typeof(*pos), member); \ &pos->member != (head); \ pos = n, n = list_entry(n->member.next, typeof(*n), member)) /** * list_for_each_entry_safe_from * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. * @member: the name of the list_struct within the struct. * * Iterate over list of given type from current point, safe against * removal of list entry. */ #define list_for_each_entry_safe_from(pos, n, head, member) \ for (n = list_entry(pos->member.next, typeof(*pos), member); \ &pos->member != (head); \ pos = n, n = list_entry(n->member.next, typeof(*n), member)) /** * list_for_each_entry_safe_reverse * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. * @member: the name of the list_struct within the struct. * * Iterate backwards over list of given type, safe against removal * of list entry. */ #define list_for_each_entry_safe_reverse(pos, n, head, member) \ for (pos = list_entry((head)->prev, typeof(*pos), member), \ n = list_entry(pos->member.prev, typeof(*pos), member); \ &pos->member != (head); \ pos = n, n = list_entry(n->member.prev, typeof(*n), member)) #endif /* LIST_H_ */

使用实例

要想使用该实现的双向链表,还需实现自己的查找操作函数。本博文简单实现如下:

struct stu_node {
	struct list_head listhead;
	int age;
};

//红黑树最大节点数目
#define STU_NUM 20

struct stu_node *stu_search(struct list_head *head, int age) {
	struct stu_node *stu = NULL;
	struct list_head *cur;
	list_for_each(cur, head) {
		stu = container_of(cur, struct stu_node, listhead);
		if (stu->age == age) {
			return stu;
		}
	}
	return NULL;
}

测试用例

void testlist() {
	struct list_head head;
	struct stu_node *stu = NULL;
	struct list_head *cur;
	int i = 0;

	INIT_LIST_HEAD(&head);
	if (1 == list_empty(&head)) {
		printf("start, list is empty \n");
	} else {
		printf("list is not empty,return \n");
		return;
	}
	//insert
	printf("start to insert element to the list \n");
	for (i = 0; i < STU_NUM; i = i + 2) {
		stu = malloc(sizeof(struct stu_node));
		stu->age = i + 10;
		list_add(&stu->listhead, &head);
	}

	for (i = 1; i < STU_NUM; i = i + 2) {
		stu = malloc(sizeof(struct stu_node));
		stu->age = i + 10;
		list_add(&stu->listhead, &head);
	}

	//travel
	printf("start to travel the list \n");

	list_for_each(cur, &head) {
		stu = container_of(cur, struct stu_node, listhead);
		printf("age %d \n", stu->age);
	}
	printf("end to travel the list \n");
	//delete
	srand(time(NULL));
	int key = rand() % STU_NUM;
	stu = stu_search(&head, 10 + key);
	if (NULL != stu) {
		printf("age %d is found, next delete it\n", stu->age);
		list_del(&stu->listhead);
		free(stu);
	} else {
		printf("age %d is not found\n", 10 + key);
	}
	stu = stu_search(&head, 10 + key);
	if (NULL != stu) {
		printf("delete age %d failed\n", 10 + key);
	} else {
		printf("delete age %d succeed\n", 10 + key);
	}

	return;
}

在main函数中,仅仅需要调用该测试接口即可。