最近遇到这样一个题: 删除一个非尾结点pos;在pos位置插入一个值为data的新结点,要求都是不能遍历链表
对于这种类型的题,首先:找到pos这个结点,然后才是调用函数删除或者插入。
于是,首先我们应该写一个能找到pos结点的函数 PNode FindDataNode(PNode pHead, DataType data)
函数代码如下:
PNode FindDataNode(PNode pHead, DataType data)
{
assert(pHead); //参数检测
PNode pCur;
pCur = pHead;
while (pCur) //遍历链表,找到值为data的结点 并且返回
{
if (data == pCur->_data)
return pCur;
pCur = pCur->_pNext;
}
printf("该结点不存在!!\n"); //没找到值为data的结点 返回空
return NULL;
}
那么如何只遍历一次就能删除pos结点呢??
思路:已知,假设找到data为2的pos结点,先将pos结点的data与其next的data交换,然后再将pos的next结点指向其next的next结点,最后再free pos结点的next结点,最终间接达到删除pos结点的效果!
代码:
void DeleteListNotTailNode(PNode pos)
{
assert(pos); //参数检测
if (NULL == pos) //该结点为空,即没找到值为data的结点
{
printf("该结点不存在!\n");
return;
}
if (NULL == pos->_pNext) //该结点为尾结点
{
printf("待删除结点为尾结点,不予删除!!\n");
return;
}
PNode pDelet = pos->_pNext;
pos->_data = pDelet->_data; //将pos位置的data 改为 其下一个结点的data
pos->_pNext = pDelet->_pNext; //将pos位置的下一个结点 改为 下一个结点的下一个结点
free(pDelet); //释放pos位置的下一个结点
pDelet = NULL; //将释放的空间赋空
}
同样的,对于pos位置的插入也可以这样做
思路:稍稍做一些改变,首先将pos结点与new结点的data交换,然后再将new结点的next链接到pos的next结点,最后再更新pos的next结点,使其的next结点改为new结点,最后达到插入的效果!
代码:
void InesrtPosFront(PNode pos, DataType data)
{
assert(pos); //参数检测
if (NULL == pos)
{
printf("该结点不存在!!\n");
return;
}
PNode pNew = BuyNewNode(data); //申请待插入新结点
pNew->_pNext = pos->_pNext; //将pNew 链接到pos位置的next
pos->_pNext = pNew;
Swap(&pos->_data, &pNew->_data); //交换pos 与 pNew 的data
}
其中调用了Swap这个交换data的函数,如下:
void Swap(DataType* left, DataType* right)
{
DataType temp;
temp = *left;
*left = *right;
*right = temp;
}
最后:奉上我的测试函数以及测试结果!
测试函数:
void testListPushAndPop()
{
PNode pHead;
PNode pos;
SListInit(&pHead);
PNodePushBack(&pHead, 1);
PNodePushBack(&pHead, 2);
PNodePushBack(&pHead, 3);
PNodePushBack(&pHead, 4);
PNodePushBack(&pHead, 5);
PNodePushBack(&pHead, 6);
printSList(pHead);
pos = FindDataNode(pHead, 3);
DeleteListNotTailNode(pos);
printSList(pHead);
pos = FindDataNode(pHead, 4);
InesrtPosFront(pos, 3);
printSList(pHead);
}
测试结果:首先一次尾插 1, 2, 3, 4, 5, 6;然后找到data为3的结点,再将其删除得到:1, 2, 4, 5, 6;最后找到data为4的结点,将data为3的结点插入得到: 1, 2, 3, 4, 5, 6 。
其他的一些小问题,可以关注我哦!谢谢大家的支持!