問題描述:假設有一個沒有頭指針的單鏈表。一個指針指向此單鏈表中間的一個節點(不是第一個,也不是最後一個節點),請將該節點從單鏈表中刪除。
一般鏈表的刪除需要順着頭結點向下找到當前待刪節點的前驅節點,然後讓前驅節點指向後驅節點就行了。這裏,沒有頭結點,就沒辦法找到前驅結點。但我們可以採用“狸貓換太子”的做法。我們把當前結點“看成”是前驅結點,把後續節點當做待刪結點刪除(刪除之前,記下後續結點的值),只需要讓當前結點指向後驅結點的後驅結點。最後把後續結點值賦給當前結點的值。
//刪除一個無頭單鏈表的非尾節點
#include<iostream>
#include<stdlib.h>
using namespace std;
typedef int DataType;
typedef struct SListNode
{
DataType data; //數據
struct SListNode* next; //指向下一個結點的指針
}SListNode;
SListNode* CreateNode(DataType x) //創造結點
{
//1.先開闢空間 2.數據賦給data 3.指針置空
SListNode* NewNode = (SListNode*)malloc(sizeof(SListNode));
NewNode->data = x;
NewNode->next = NULL;
return NewNode;
}
void PushBack(SListNode* &ppHead, int Data)
{
//1.none 2.one and more
if (ppHead == NULL)
{
ppHead = CreateNode(Data);
}
else
{
//1.先找到尾結點 2.把新節點鏈起來
SListNode* cur = ppHead;
while (cur->next)
{
cur = cur->next;
}
cur->next = CreateNode(Data);
}
}
//刪除一個無頭單鏈表的非尾節點
void DelNoHeadNotTail(SListNode* &ppHead , int pos)
{
if (ppHead == NULL) //邊界條件檢查
return;
else
{
SListNode* prev = ppHead; //prev指向要刪除結點的前一個結點
SListNode* cur = prev->next; //cur指向要刪除節點
while (cur->data!= pos)
{
cur = cur->next;
prev = prev->next;
}
prev->next = cur->next;
free(cur);
cur->next = NULL;
}
}
void PrintSNodeList(SListNode*&ppHead)
{
while (ppHead)
{
printf("%d->", ppHead->data);
ppHead = ppHead->next;
}
cout << "NULL";
printf("\n");
}
void Test()
{
SListNode* pHead = NULL;
PushBack(pHead, 1);
PushBack(pHead, 2);
PushBack(pHead, 3);
PushBack(pHead, 4);
PushBack(pHead, 5);
DelNoHeadNotTail(pHead, 2);
PrintSNodeList(pHead);
}
int main()
{
Test();
system("pause");
return 0;
}