想起之前面试,有个面试官给出了一个单链表的head头指针,以及要删除的p节点,让我说出要如何删除该p节点。
我爽快的说,只需要获取到p节点的前驱结点p->pre, p->pre->next = p->next. free(p),考官说,是单链表,不是双链表、
我又迅速地说,那就借助head指针,一直找,找到p节点,并保留p的前一个指针不就可以了。
考官说,要是这个链表数据很多,这样做,会有点慢,让我再想想,相当于提供了一个不知道头结点的单链表。
后来网路上看到别人说有一种叫狸猫换太子的算法,可以巧妙地删除某一个链表的节点(非尾节点)。
架设有个一链表 head - > A -> B -> C -> D -> E -> F -> G -> NULL,要删除 C 节点,指向 C 节点的指针叫 pDelet,
思路:用 C 节点的下一个 节点 D 来作为要删除的节点。将 D 节点的 data 传给 C 节点的 data ,再将 C 的 next 指针指向 D 的next 节点,释放 D 节点。
即: pDelet->data = pDelet->next->data;
pDelet->next = pDelet->nexxt->next;
free(pDelet);
算法如下:
woid DeletOneNode(node *p)
{
Assert(p != NULL);
node * pNext = p->next;
if(pNext != NULL){ //判断要删除的节点是不是最后一个节点
p->data = pNext->data;
p ->next = pNext->next;
free(pNext);
}else{ //p是尾节点
printf("This is the Rear node,you can't delete it");
}
}
但是,一般涉及到要经常删除和添加节点的链表,一般都是采用双链表。
思考:如何保证p->data 没有内存泄露问题, pNext-.>data 不会重复释放?