单向链表
链表简介:
链表是一种简单的数据结构(单链表、双链表、循环链表),而且是一种线性表,但是其储存数据的方式是非线性的。这样就有区别于数组了,数组储存数据的方式是线性的,既是储存在一块连续的内存空间里。使用链表时无需先要知道要分配多大的内存空间,而是根据自己的需求来分配,这样,我们就能充分地利用内存空间。同时,链表能快速地插入和删除其中的某个元素,在内存管理、插入删除元素上,链表比数组有很大的优势,但是,正是由于链表的非线性储存方式,导致了不能提供随机访问的缺点。
因此,链表的优势在于能根据需求来动态分配内存,频繁插入及删除数据,而访问、查找数据是弱项(时间复杂度都比较高)。
单向链表结构图解:
单链表的实现 :
单链表由若干个节点(node)组成,而每个节点又是由数据项(item)以及链接到下一个节点的信息(pointer)组成。
节点描述-------
struct node
{
Item item;
struct node *next;
};
一开始链表没有节点,因此没有哪个节点的链接信息能找到第一个节点的,自然而然地,我们便想到需要一个独立的头指针 (head pointer) 来指向链表的第一个节点。而这里,直接创建一个指向链表节点的指针则显得更为通用。
----------------------------------------C实现单链表头文件------------------------------------------
#ifndef _LIST_H_
#define _LIST_H_
#define SIZE 30
typedef int Item;
typedef struct node
{
Item item; /*数据项*/
struct node *next; /*链接指针*/
}Node;
typedef Node *List; /*指向节点的指针*/
/*初始化链表*/
/*作用:将链表初始化为空链表*/
void initialize_list(List *plist);
/*清空链表*/
/*作用:释放为链表分配的内存*/
void empty_list(List *plist);
/*添加数据项到链表*/
/*作用:在链表尾添加一个新节点并添加数据*/
bool add_item(List *plist,Item item);
/*删除链表的数据项*/
/*作用:在链表中找到储存有与指定数据项相同数据的节点,
并释放其内存*/
bool delete_item(List *plist,Item item);
/*查找数据*/
/*作用:在链表中找到储存有与指定数据项相同数据的节点,
并返回指向该节点的指针*/
Node * find_item(const List *plist,Item item);
/*判断列表是否为空*/
/*作用:链表为空返回true,否则返回false*/
bool is_empty(const List *plist);
/*统计链表中的项目数*/
/*作用:遍历链表,返回累加的项目数*/
unsigned int item_count(const List *plist);
/*显示链表内容*/
/*作用:遍历并显示整个表*/
void display_list(const List *plist);
/*构造新节点*/
/*作用:为新节点分配内存,并返回指向该节点的指针*/
Node * construct_node(const Item item);
#endif
---------------------------------------C实现单链表各部分功能---------------------------------------
初始化链表
void initialize_list(List *plist)
{
*plist=NULL;
}
清空链表
void empty_list(List *plist)
{
Node *pTemp;
while (*plist!=NULL)
{
pTemp=(*plist)->next;
free(*plist);
*plist=pTemp;
}
}
插入数据
bool add_item(List *plist,Item item)
{
Node *pNew;
Node *current=*plist;
if (!(pNew=construct_node(item)))
return false;
if (is_empty(plist))
*plist=pNew;
else
{
while (current->next!=NULL)
current=current->next;
current->next=pNew;
}
return true;
}
删除数据
bool delete_item(List *plist,Item item)
{
Node *prev;
Node *current=*plist;
if (is_empty(plist))
return false;
while (current!=NULL)
{
if (current->item==item)
{
prev->next=current->next;
free(current);
return true;
}
prev=current;
current=current->next;
}
return false;
}
查找数据
Node * find_item(const List *plist,Item item)
{
Node *current=*plist;
if (is_empty(plist))
return NULL;
while (current!=NULL)
{
if (current->item==item)
return current;
current=current->next;
}
return NULL;
}
判断链表是否为空
bool is_empty(const List *plist)
{
if (*plist==NULL)
return true;
else
return false;
}
统计数据数量
unsigned int item_count(const List *plist)
{
unsigned int count=0;
Node *current=*plist;
if (is_empty(plist))
return 0;
while (current!=NULL)
{
++count;
current=current->next;
}
return count;
}
显示链表数据
void display_list(const List *plist)
{
Node *current=*plist;
while (current!=NULL)
{
printf("%d\n",current->item);
current=current->next;
}
}
构建链表新节点
Node * construct_node(const Item item)
{
Node *pNode=(Node *)malloc(sizeof(Node));
if (!pNode)
return NULL;
pNode->item=item;
pNode->next=NULL;
return pNode;
}
初次学数据结构,我就写这么多了,有什么错误大家可以提出啊,我会改正的,不过还是觉得链表比较好懂的,代码我运行过了,也没发现什么BUG。
^_^
完