首先给出链表节点的定义:
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
typedef int DataType;
typedef struct SListNode
{
DataType data;
struct SListNode *pNext;
} SListNode;
- 删除一个无头单链表的非尾结点(不能遍历链表)
思路:本题要求不能遍历链表,那么在知道所删节点信息后,我们能够知道的只有该节点及该节点后面的节点信息,所以我们只能利用该节点后面的结点来达到删除该节点的目的。我们可以定义一个指针指向要删除节点的下一个节点,并将要删除结点的data和pNext都更新为下一个结点的data和pNext值,然后释放所定义的指针。简言之就是用所要删除节点的下一个结点来替换该节点,并删除该节点的下一个节点。
// 删除无头链表的非尾结点(替换删除)
void RemoveNodeNotTail(SListNode *pos)
{
SListNode *pCur = pos->pNext;
pos->data = pCur->data;
pos->pNext = pCur->pNext;
free(pCur);
}
- 插入一个节点到无头单链表(不能遍历链表)
思路: 同样,在只知道要插入节点的位置及要插入的数据时,我们能利用地也只有该节点后面的节点。首先也是将要插入节点位置的节点信息复制一份,并保存在一个新节点中,然后将要插入节点位置的节点信息分别更新为data和前面所求的新节点。
//无头链表前插入(替换插入)
void InsertNoHead(SListNode *pos, int data)
{
SListNode *pCur;
pCur = (SListNode *)malloc(sizeof(SListNode));
pCur->data = pos->data;
pCur->pNext = pos->pNext;
pos->data = data;
pos->pNext = pCur;
}