#include<iostream>
#include<math.h>
using namespace std;
struct ListNode
{
int nValue;
struct ListNode *pNext;
};
//如果这个函数参数传递的是一个指针,则函数会定义个指针pp指向实参所指向的地址,即和p指向同一个内存
//函数内部对指针pp内容的改变,同时会影响到p的内容,因为两个指针指向同一个内存。但是如果把pp指向其他的
//内存,即对pp进行重新赋值,然后对pp的内容的改变,不会影响到p的内容,因为此时两个指针指向不同的内存了
//所以要想改变指针pp的指向的情况下,对指针pp的改变同时影响到p的内容,可以参数传递指针的指针,即p的地址,这样
//在函数内,通过*pp = q; q是一个新的指针,指向不同的地址。
//ListNode* CreateList(ListNode* pp)
ListNode* CreateList(ListNode** pp)
{
int a;
ListNode *pHead = NULL;
ListNode *pCur = NULL;
int i = 1;
while(cin>>a && a)
{
ListNode *p = new ListNode;
p->nValue = a;
p->pNext = NULL;
if(i++ == 6)
*pp = p;
/*p->pNext = pHead;
pHead = p;*/
//----------------------------------------
if(pCur == NULL)
{
pHead = p;
pCur = p;
}
else
{
pCur->pNext = p;
pCur = p;
}
//----------------------------------------
}
return pHead;
}
//删除p指针指向的节点
ListNode* DeletePNode(ListNode* pHead, ListNode* p)
{
//如果pHead或p为NULL直接返回pHead
if(pHead == NULL || p == NULL)
return pHead;
//如果要删除的是最后一个节点,则必须要从头遍历到倒数第二个节点,因为如法直接把最后一个节点赋值为NULL
if(p->pNext == NULL)
{
//如果只有一个头结点,则直接返回NULL
if(pHead == p)
return NULL;
else
{
//否则从头遍历到倒数第二个节点,然后删除最后一个节点
ListNode* q = pHead;
while(q->pNext != p)
q = q->pNext;
q->pNext = NULL;
}
}
else
{
//如果删除的不是最后一个节点,则把要删除的节点的后一个节点的nValue值和pNext指针赋给要删除的节点
//即把后一个节点的内容赋给删除节点,然后删除后一个节点,即是间接删除了要删除节点,实质上是删除了后一个节点
ListNode* temp = p->pNext;
p->nValue = temp->nValue;
p->pNext = temp->pNext;
delete temp;
temp = NULL;
}
return pHead;
}
int main(int argc,char* argv[])
{
//ListNode* p只是申明了一个指针,没有定义,所以没有分配内存空间,不能作为参数传递CreateList(p),
//只能new一个对象给它才是定义,分配内存空间,即指针指向一个地址
ListNode* p = new ListNode;
//ListNode* pHead = CreateList(p);
ListNode* pHead = CreateList(&p);
pHead = DeletePNode(pHead,p);
system("pause");
return 0;
}