现在的位置: 首页 > 综合 > 正文

C语言练习01:单向链表的实现

2013年01月28日 ⁄ 综合 ⁄ 共 4423字 ⁄ 字号 评论关闭

实现了向链表的尾部追加节点、删除节点、遍历节点。

头文件:

/*
 * List.h
 * 
 * Single linked list header file
 *
 * By Yaping Xin 110929
 *
 */

#ifndef _LIST_H_
#define _LIST_H_

#define LIST_NEED_COUNT

#include "CustomizedTypes.h"

struct Node_Struct
{
	Item item;
	struct Node_Struct *next;
};

typedef struct Node_Struct Node;
typedef Node * Link;

struct List_Struct
{
	Node * begin;
	Node * end;
#ifdef LIST_NEED_COUNT
	unsigned __int32 count;
#endif
};

typedef struct List_Struct List;

/* initializes the linked list by putting NULL into the pointers 
 * containing the first and last links of the linked list. 
 */
List * InitializeList(List *list);

/* release the allocated memory */
void DisposeList(List *list);

/* adds a new link to the end of the linked list */
Node * ListAppendNode(List *list, Item item);

/* Go through the list and operate on the data of each element with "callback". */
void ListTraverse(List *list, void (*callback) (Item item));

/* Remove a node from the single linked list.
 * If node is not list->begin, then previous node should be provided.
 * If node is list->begin, previous node parameter will not be used in the function.
 */
Node * ListRemoveNode(List *list, Node *node, Node *prev);

/* Remove a item from the single linked list */
Node * ListRemoveItem(List *list, Item item);


#endif /* _LIST_H_ */

实现:

/*
 * List.c
 * 
 * Single linked list implementation
 *
 * By Yaping Xin 110929
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include "List.h"

/* initializes the linked list by putting NULL into the pointers 
 * containing the first and last links of the linked list. 
 */
List * InitializeList(List *list)
{
	if(!list)
	{
		list = (List *)calloc(1, sizeof(List));
	}

	list->begin = list->end = NULL;
#ifdef LIST_NEED_COUNT
	list->count = 0;
#endif

	return list;
}

/* release the allocated memory */
void DisposeList(List *list)
{
	Node * link;
	Node * next;
	for(link = list->begin; link != NULL; link = next)
	{
		next = link->next;
		free(link);
	}

	list->begin = list->end = NULL;
#ifdef LIST_NEED_COUNT
	list->count = 0;
#endif
}

/* adds a new link to the end of the linked list */
Node * ListAppendNode(List *list, Item item)
{
	Node * link;

	link = (Node *)calloc(1, sizeof(Node));
	if(!link)
	{
		fprintf(stderr, "calloc failed when allocate memory space for new Node.\n");
		exit(1);
	}

	link->item = item;
	link->next = NULL;

	if(list->end)
	{
		list->end->next = link;
		list->end = link;
	}
	else
	{
		list->begin = link;
		list->end = link;
	}

#ifdef LIST_NEED_COUNT
	list->count ++;
#endif
	return link;
}

/* Go through the list and operate on the data of each element with "callback". */
void ListTraverse(List *list, void (*callback) (Item item))
{
	Node * link;

	for (link = list->begin; link; link = link->next)
	{
		callback(link->item);
	}
}

/* Remove a node from the single linked list.
 * If node is not list->begin, then previous node should be provided.
 * If node is list->begin, previous node parameter will not be used in the function.
 */
Node * ListRemoveNode(List *list, Node *node, Node *prev)
{
	if(!node)
	{
		fprintf(stderr, "the node is not exist.\n");
		exit(1);
	}

	if(!list || !list->begin || list->begin==list->end)
	{
		fprintf(stderr, "list is empty, cannot remove node from it.\n");
		exit(1);
	}

	if(node == list->begin)
	{
		list->begin = list->begin->next;
		
		free(node);
#ifdef LIST_NEED_COUNT
		list->count --;
#endif

		return list->begin;
	}

	prev->next = node == list->end ? NULL : node->next;

	free(node);
#ifdef LIST_NEED_COUNT
	list->count --;
#endif

	return prev->next;
}

/* Remove a item from the single linked list */
Node * ListRemoveItem(List *list, Item item)
{
	Node * prev;
	Node * node;

	if(!list || !list->begin || list->begin==list->end)
	{
		fprintf(stderr, "list is empty, cannot remove node from it.\n");
		exit(1);
	}

	if(CompareItems(item, list->begin->item) == 0)
	{
		return ListRemoveNode(list, list->begin, NULL);
	}

	for(prev = list->begin, node = list->begin->next; node; prev = prev->next, node = node->next)
	{
		if(CompareItems(item, node->item) == 0)
		{
			return ListRemoveNode(list, node, prev);
		}
	}

	return NULL;
}

涉及到的自定义类型:

/*
 * CustomizedTypes.h
 * 
 * Customized types definition
 *
 * By Yaping Xin 110929
 *
 */

#ifndef _CustomizedTypes_H_
#define _CustomizedTypes_H_

/* typedef unsigned __int32 Item; */

typedef unsigned __int32 UInt32;

struct Item_Struct
{
	UInt32 data;
	//UInt32 offset;
};

typedef struct Item_Struct Item;

Item CreateEmptyItem();
Item CreateItem(unsigned __int32 data);
int CompareItems(Item value0, Item value1);

typedef struct
{
	UInt32 x;
	UInt32 y;
} ItemPair;


#endif /* _CustomizedTypes_H_ */

/*
 * CustomizedTypes.c
 * 
 * Customized types implementation
 *
 * By Yaping Xin 110929
 *
 */

#include <string.h>
#include "CustomizedTypes.h"

Item CreateEmptyItem()
{
	Item result;
	result.data = 0;
	//result.offset = 0;

	return result;
}

Item CreateItem(unsigned __int32 data)
{
	Item result;
	result.data = data;
	//result.offset = data;

	return result;
}

int CompareItems(Item value0, Item value1)
{
	return memcmp(&value0, &value1, sizeof(Item));
}

调用方法:

初始化链表:

List list;
InitializeList(&list);

释放链表:

DisposeList(&list);

向链表中追加一个元素:

ListAppendNode(&list, CreateItem(5));

遍历打印链表:

首先定义一个函数:

void print_node(Item item)
{
	printf("data: %6dn", item.data);
}

然后就可以这样遍历并打印链表:

ListTraverse(&list, print_node);

本练习到此结束。本文仅仅是一个小小的练习,欢迎您提出改进意见。

抱歉!评论已关闭.