您的位置:首页 > Web前端

剑指Offer系列---(16)在O(1)时间删除链表结点

2015-09-10 11:34 344 查看
1.题目描述:

给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。链表结点与函数的定义如下:

struct ListNode

{

int m_nValue;

ListNode* m_pNext;

};

void DeleteNode(ListNode** pListHead,ListNode* pToBeDeleted);

2.分析:

1)在单向链表中删除一个结点,最常规的做法无疑是从链表的头结点开始,顺序遍历查找要删除的结点,并在链表中删除该节点。

2)如果我们把下一个结点的内容复制到需要删除的结点上覆盖原来的内容,再把下一个结点删除,那就相当于把当前结点删除了。

3)此方法的前提是结点存在于链表内,删除最后一个结点时比较特殊。

3.源代码:

//  Copyright (c) 2015年 skewrain. All rights reserved.

#include <iostream>
#include <stdio.h>
#include <stack>
using namespace std;

struct ListNode
{
int m_nValue;
ListNode *m_pNext;
};

ListNode* CreateLink(int a[],int k)
{
ListNode *Head = NULL,*q = NULL;
for (int i=0; i<k; i++)
{
ListNode *pNew = new ListNode();
pNew->m_nValue = a[i];
pNew->m_pNext = NULL;

if(Head==NULL)
{
Head = pNew;
q = pNew;
}
else
{
q->m_pNext = pNew;
q = pNew;
}
}
return Head;
}

//从头到尾打印列表
void printLink(ListNode *pHead)
{
cout<<"链表内容为:";
ListNode *p = pHead;
while (p) {
cout<<p->m_nValue<<" ";
p=p->m_pNext;
}
cout<<endl;
}

void DeleteNode(ListNode** pListHead,ListNode* pToBeDeleted)
{
if (!pListHead || !pToBeDeleted) {
return;
}
//要删除的结点不是尾结点
if (pToBeDeleted->m_pNext!=NULL)
{
ListNode* pNext = pToBeDeleted->m_pNext;
pToBeDeleted->m_nValue = pNext->m_nValue;
pToBeDeleted->m_pNext = pNext->m_pNext;

delete pNext;
pNext = NULL;
}
//链表只有一个结点,删除头结点(也是尾结点)
else if (*pListHead == pToBeDeleted)
{
delete pToBeDeleted;
pToBeDeleted = NULL;
*pListHead = NULL;
}
//链表中有多个结点,删除尾结点
else
{
ListNode* pNode = *pListHead;
while (pNode->m_pNext != pToBeDeleted) {
pNode = pNode->m_pNext;
}
pNode->m_pNext = NULL;
delete pToBeDeleted;
pToBeDeleted = NULL;
}
}

//--------测试用例--------
//1.链表中有多个结点,删除尾结点
void Test1()
{
cout<<"测试用例1"<<endl;
int a[] = {1,2,3};
ListNode *ptr = CreateLink(a,3);
ListNode *del = ptr;
while (del->m_nValue!=3) {
del = del->m_pNext;
}
cout<<"删除结点前:";
printLink(ptr);
DeleteNode(&ptr, del);
cout<<"删除结点后:";
printLink(ptr);
}

//2.链表中有多个结点,删除尾结点
void Test2()
{
cout<<"测试用例2"<<endl;
int a[] = {1,2,3};
ListNode *ptr = CreateLink(a,3);
ListNode *del = ptr;
while (del->m_nValue!=1) {
del = del->m_pNext;
}
cout<<"删除结点前:";
printLink(ptr);
DeleteNode(&ptr, del);
cout<<"删除结点后:";
printLink(ptr);
}

//3.链表中有多个结点,删除尾结点
void Test3()
{
cout<<"测试用例3"<<endl;
int a[] = {1,2,3};
ListNode *ptr = CreateLink(a,3);
ListNode *del = ptr;
while (del->m_nValue!=2) {
del = del->m_pNext;
}
cout<<"删除结点前:";
printLink(ptr);
DeleteNode(&ptr, del);
cout<<"删除结点后:";
printLink(ptr);
}

//4.链表中有多个结点,删除尾结点
void Test4()
{
cout<<"测试用例4"<<endl;
int a[] = {1};
ListNode *ptr = CreateLink(a,1);
ListNode *del = ptr;
while (del->m_nValue!=1) {
del = del->m_pNext;
}
cout<<"删除结点前:";
printLink(ptr);
DeleteNode(&ptr, del);
cout<<"删除结点后:";
printLink(ptr);
}

//5.链表中有多个结点,删除尾结点
void Test5()
{
cout<<"测试用例5"<<endl;
ListNode *ptr = NULL;
ListNode *del = ptr;
cout<<"删除结点前:";
printLink(ptr);
DeleteNode(&ptr, del);
cout<<"删除结点后:";
printLink(ptr);
}
int main(int argc,char *argv[]){

Test1();
Test2();
Test3();
Test4();
Test5();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: