您的位置:首页 > 其它

关于单链表的基本操作

2017-07-15 17:24 260 查看
在顺序表中,我们需要头插或者在顺序表的中间位置插入元素时,就必须将后面的元素一一后移,再将需要插入的元素插入进去。可是这样的效率明显很低,所以就想到了单链表这种数据结构,可以将在物理地址上不连续的数据连接起来,需要连接,那么就需要有一个保存下一个元素地址的指针,可是没有这样的内置类型供我们使用,所以这时就需要我们自定义一个类型,在C语言中我们可以使用结构体来构造。



1.初始化单链表:

void InitListNode(PNode *pHead)
{
assert(pHead);
*pHead = NULL;
}


2.构建一个节点:

PNode BuyNode(DataType _data)
{
PNode node = (PNode)malloc(sizeof(Node));
if (node)
{
node->data = _data;
node->next = NULL;
}
return node;
}


3.尾插:



void PushBack(PNode *pHead,DataType _data)
{
assert(pHead);
PNode newNode = BuyNode(_data);
if (NULL == (*pHead))
{
*pHead = newNode;
return ;
}
PNode pCur = *pHead;
while (pCur->next)
{
pCur = pCur->next;
}
pCur->next = newNode;
}


4.尾删:



void PopBack(PNode *pHead)
{
assert(pHead);
if (NULL == (*pHead))
{
return ;
}
else if (NULL == (*pHead)->next)
{
free(*pHead);
*pHead = NULL;
}
else
{
PNode pCur = *pHead;
PNode prev = pCur;
while (pCur->next)
{
prev = pCur;
pCur = pCur->next;
}
free(pCur);
prev ->next = NULL;
}
}


5.头插:



void PushFront(PNode *pHead,DataType _data)
{
assert(pHead);
PNode newNode = BuyNode(_data);
if (NULL == (*pHead))
{
*pHead = newNode;
}
else
{
if (newNode)
{
newNode->next = *pHead;
*pHead = newNode;
}
}
}


6.头删:



void PopFront(PNode *pHead)
{
assert(pHead);
if (NULL == (*pHead))
{
return ;
}
PNode pDel = *pHead;
*pHead = (*pHead)->next;
free(pDel);
}


7.查找一个值为data的节点,如果存在,返回所在位置,否则,返回NULL

只需要遍历一遍链表即可。

PNode Find(PNode pHead, DataType _data)
{
if (NULL == pHead)
{
return NULL;
}
PNode pCur = pHead;
while (pCur)
{
if (pCur->data == _data)
{
return pCur;
}
pCur = pCur->next;
}
return NULL;
}
//插入一个节点
void InsertNode(PNode pos,DataType _data)
{
if (pos)
{
PNode newNode = BuyNode(_data);
if (newNode)
{
newNode->next = pos->next;
pos->next = newNode;
}
}
}


8.插入一个节点(由于是单链表,所以只能插在pos位置的后面)

需考虑的因素:

①检查参数(链表是否存在,pos位置是否为空)

②当pos位置不空时:如图示



void InsertNode(PNode pos,DataType _data)
{
if (pos)
{
PNode newNode = BuyNode(_data);
if (newNode)
{
newNode->next = pos->next;
pos->next = newNode;
}
}
}


9.删除pos位置上的一个节点:

需要考虑的因素:

①链表为空和pos为空,直接返回

②pos不为空且pos为1时,这时就可以转化为删除第一个节点,操作步骤同上面的头删

③当pos不是第一个节点时,分析如图示:



void Erase(PNode* pHead, PNode pos)
{
assert(pHead);
if ((NULL == (*pHead)) && (NULL == pos))
{
return ;
}
if((*pHead) == pos)
{
*pHead = pos->next;
free(pos);
}
else
{
PNode pCur = *pHead;
while (pCur ->next != pos)
{
pCur = pCur->next;
}
pCur->next = pos->next;
free(pos);
}
}


10.

删除单链表中值为_data的节点:

代码实现:

void Remove(PNode* pHead, DataType _data)

{

assert(pHead);

Erase(pHead, Find(*pHead,_data));

}


11.删除单链表中所有值为_data的节点:
需考虑:

①第一个节点的值是_data,因为删除第一个节点需要修改phead的值,所以需要单独处理第一个节点的值是_data的时候。

删除第一个节点就是上面所说的头删。

②如果第一个节点的值不是_data,直接处理即可。

下面处理第一个值不是_data(这里的_data为2)的情况:



void RemoveAll(PNode *pHead, DataType _data)
{
assert(pHead);
if (NULL == (*pHead))
{
return ;
}
PNode pDel = *pHead;
if ((*pHead)->data == _data)
{
*pHead = (*pHead)->next;
free(pDel);
}
PNode pCur = *pHead;
PNode prev = pCur;
while (pCur)
{
if (pCur->data == _data)
{
prev->next = pCur->next;
free(pCur);
pCur = prev->next;
}
else
{
prev = pCur;
pCur = pCur->next;
}
}
}


12.打印单链表:

void printList(PNode phead)
{
PNode pCur = phead;
while (pCur)
{
printf("%d ",pCur->data);
pCur = pCur->next;
}
printf("\n");
}


13.得到单链表中节点的个数:

size_t Size(PNode pHead)
{
size_t count = 0;
while (pHead)
{
pHead = pHead->next;
count++;
}
return count;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: