问题描述:
假设有一个没有头指针的单链表。一个指针指向此单链表中间的一个节点(非第一个节点, 也非最后一个节点)。请将该节点从单链表中删除。
解法:
假定给定指针为pCurrent,Node *pNext = pCurrent->next(pNext指向pCurrent所指节点的下一个节点)。
由于没有头结点,因此只能考虑删掉pCurrent->next,而不能删掉pCurrent,否则断链。先将pNext的数据复制到pCurrent,然后删掉pNext就行了,代码如下:
struct Node{
int data;
Node *next;
};
void deleteRandom(Node *pCurrent)
{
if(pCurrent == NULL)
return;
Node *pNext = pCurrent->next;
if(pNext != NULL){
//---复制pNext数据到pCurrent
pCurrent->data = pNext->data;
//---链接与删除
pCurrent->next = pNext->next;
delete pNext;
}
}
扩展问题:
1.向无头单链表添加节点,一个指针pCurrent指向某节点(不是第一个,不是最后一个),在该节点前面插入一个节点pNew
解法:因为无头,所以访问前驱节点不可能,因此依旧是依照移花接木的思路,先将pNew插在pCurrent后面,然后交换二者的数据区即可。
void insertRandom(Node *pCurrent,Node *pNew)
{
if(pCurrent==NULL || pNew==NULL)
return;
Node *pNext = pCurrent->next;
if(pNext != NULL){
//---将pNew插在pCurrent和pNext之间
pNew->next = pNext;
pCurrent->next = pNew;
//---交换pNew和pCurrent数据区
int temp = pCurrent->data;
pCurrent->data = pNew->data;
pNew->data = temp;
}
}
2.编写一个函数,给定一个链表的头指针,要求只遍历一次,将此链表中的元素顺序反过来。
解法:用三个指针分别指向当前、前驱和后继节点,将节点指向倒置即可。代码如下:
//只遍历一次倒置所有元素
//考虑除头结点外,置header->next->next=null,然后遍历时将所有结点的next指向前驱,接着将header->next=最后一个节点
void reverseList(Node *Head)
{
Node *pPre,*pCurrent,*pNext ,*Tail;//保存前驱节点和当前节点以及后驱节点
pPre = pCurrent = pNext = Tail = Head->next;
while(pCurrent != NULL){
pNext = pCurrent->next;
pCurrent->next = pPre;//指向前驱
pPre = pCurrent;//后移前驱
pCurrent = pNext;//pNext=NULL时跳出,即pPre为最后一个节点时跳出
}
Head->next = pPre;
Tail->next = NULL;
}