编程之美——从无头单链表中删除节点
问题:假设有一个没有头指针的单链表。一个指针指向此单链表中间的一个节点,请将该节点从单链表中删除。
分析:典型的“狸猫换太子”, 若要删除该节点,正常情况下,应该要知道该节点的前面节点的指针,但是由于单链表中没有头结点,所以无法追溯到该节点前面的那个节点,因此,这里采用了“移花接木”的方法。设该节点为B,下一个节点为C。那么,首先将B节点的内容替换为C节点的内容,然后,将C节点删除,这样就达到了我们的目的。代码如下:
// lianbiao.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef struct node{
int data;
node *next;
}Node;
void deleteNode(Node *pCurrent,Node *head)
{
if(pCurrent!=NULL)
{
if(pCurrent->next!=NULL)
{
Node *pTemp=pCurrent->next;
pCurrent->data=pTemp->data;
pCurrent->next=pTemp->next;
delete pTemp;
}
else
{
Node *temp=head;
while(temp!=NULL)
{
if(temp->next==pCurrent)
{
delete pCurrent;
temp->next=NULL;
}
temp=temp->next;
}
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Node *n1=new Node();
Node *n2=new Node();
Node *n3=new Node();
n1->data=1;
n1->next=n2;
n2->data=2;
n2->next=n3;
n3->data=3;
n3->next=NULL;
printf("before delete:");
Node *temp=n1;
while(temp!=NULL)
{
printf("%d",temp->data);
temp=temp->next;
}
printf("after delete:");
deleteNode(n3,n1);
temp=n1;
while(temp!=NULL)
{
printf("%d",temp->data);
temp=temp->next;
}
system("pause");
return 0;
}
//
#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef struct node{
int data;
node *next;
}Node;
void deleteNode(Node *pCurrent,Node *head)
{
if(pCurrent!=NULL)
{
if(pCurrent->next!=NULL)
{
Node *pTemp=pCurrent->next;
pCurrent->data=pTemp->data;
pCurrent->next=pTemp->next;
delete pTemp;
}
else
{
Node *temp=head;
while(temp!=NULL)
{
if(temp->next==pCurrent)
{
delete pCurrent;
temp->next=NULL;
}
temp=temp->next;
}
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Node *n1=new Node();
Node *n2=new Node();
Node *n3=new Node();
n1->data=1;
n1->next=n2;
n2->data=2;
n2->next=n3;
n3->data=3;
n3->next=NULL;
printf("before delete:");
Node *temp=n1;
while(temp!=NULL)
{
printf("%d",temp->data);
temp=temp->next;
}
printf("after delete:");
deleteNode(n3,n1);
temp=n1;
while(temp!=NULL)
{
printf("%d",temp->data);
temp=temp->next;
}
system("pause");
return 0;
}
拓展题:编写一个函数,给定一个链表的头指针,要求只遍历一次,将单链表中的元素顺序反转过来。
分析:可以用三个指针进行遍历,在遍历的途中,进行逆置。
核心代码为:
void Reverse(Node *head)
{
if(head==NULL)
return;
Node* prev=NULL;
Node* curr=head;
Node* next=NULL;
while(curr)
{
next=curr->next;
curr->next=prev;
prev=curr;
curr=next;
}
}
{
if(head==NULL)
return;
Node* prev=NULL;
Node* curr=head;
Node* next=NULL;
while(curr)
{
next=curr->next;
curr->next=prev;
prev=curr;
curr=next;
}
}