在讲述链表之前让我们对数据结构进行一个简单的回顾:我们知道,数据结构指的是描述实际问题中各个数据项节点之间的前后逻辑结构关系,即要么是线性结构(即某一数据项的前继节点和后继节点有且只有一个)要么是非线性结构(即某一数据节点的前驱或者后继节点不止一个)。在确定了实际数据项的数据结构之后,我们要采用某种存储方式对其进行存储,常见的数据结构的存储方式有:顺序存储、链式存储、散列存储以及索引存储。每一种存储方式都有一个基础数据结构与其对应,如数组是顺序存储的基础数据结构,链表是链式存储基础数据结构等等。所以彻底理解了链表也即会非常容易的理解其他基于链式存储的数据结构。
链表:根据指针域的不同,链表分为单向链表、双向链表、循环链表等等。
单向链表是链表中最简单的,每个元素包含一个指针域和一个数值域,我们称这样的元素为一个节点,每个节点用来存储实际数据中的一个数据项,每个节点的指针域指向下一个节点,最后一个指向一个空值。即一个单项链表的一个节点分为两个部分,第一部分保存或者显示关于节点的信息,第二部分存储下一个节点的地址,单链表只能向一个方向进行遍历。下面我们来具体实现一个单链表:
首先我们要定义一个节点,用于保存数据项的各项信息:
typedef Node
{
int data;
Node * pNextNode;
}linkNode;
生成一个包含nCount个节点的链表:
linkNode* createLink(int nCount)//尾插法
{
linkNode *pHeadNode = malloc(sizeof(linkNode));
linkNode * p = null;
for(int i = 0; i<nCount; i++)
{
p = malloc(siezof(linkNode))
p->data = i;
pHeadNode->next = p;
pHeadNode = p;
}
p->next = null;
return pHeadNode
}
删除链表某一个节点:
linkNode * deleteNode(linkNode * pHeadNode, int theData)
{
while(pHeadNode->data==theData)//判断链表头结点是否是需要删除的节点
{
pHeadNode= pHeadNode->next;
if(pHeadNode== null) return null;
}
while(pHeadNode->next!=null)
{
if(pHeadNode->next->data==theData)
pHeadNode->next = pHeadNode->next->next;
else
pHeadNode = pHeadNode->next;
}
return pHeadNode;
}
查找链表中包含某一元素的节点
linkNode* searchNode(linkNode *pHeadNode, int theData)
{
while(pHeadNode->data==theData)
return pHeadNode;
while(pHeadNode->next!=null && pHeadNode->data!=theData)
pHeadNdoe = pHeadNode->next;
return pHeadNode;
}
在链表中,在pos位置增加一个元素:
linkNode* addNode(linkNode* pHeadNode, int pos, int number)
{
for(int i = 0; i<pos; i++)
{
pHeadNode = pHeadNode->next;
}
linkNode* theAddNode = malloc(sizeof(linkNode));
theAddNode->data = number
theAddNode->next = pHeadNode->next;
pHeadNode->next = theAddNode;
}
链表的遍历
void printLink(linkNode* pHeadNode)
{
if(pHeadNode==null)
return;
while(pHeadNode->next!=nul)
pHeadNode = pHeadNode->next;
}
到此我们完成了单向链表的一部分功能,当然代码不是特别完善,所以我会不定时更新完善这部分。当然还有双向链表和循环链表等,但在此就不一一介绍了,后面有需要的会补上来的。