博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
面试题13:在O(1)时间删除链表结点
阅读量:7193 次
发布时间:2019-06-29

本文共 2578 字,大约阅读时间需要 8 分钟。

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

 链表结点与函数的定义如下:

struct ListNode{    int m_nValue;    ListNode* m_pNext;};void DeleteNode(ListNode** pListHead,ListNode* pToBeDeleted);

删除结点的操作我们经常碰到,比如一个链表A->B->C->D->E->F->G。如果我们要删除结点E,那么我们只需要让结点D的指针指向结点F即可,但是我们现在只给出链表头结点的指针以及结点E的指针,而又是单项链表,不能在O(1)时间内得到被删除结点前面的那一个结点的指针,所以我们原先的方法是不能在O(1)时间内删除结点E的。

那么既然我们不能获得被删除结点的前一个结点的指针,我们就需要转变思路来考虑是否能够用过被删除结点后一个结点的指针来解决方法。因此被删除结点E的后一个结点指针是很容易得到的,也就是E->m_pNext。

那么我们可能会想到如下方法:获得F的指针,将F的数据赋值给E,然后让E指向F的下一个结点。这里虽然删除的是结点F,但是相当于删除的是结点E。并且是O(1)时间复杂度。下面给出代码实例:

View Code
#include
#include
#include
using namespace std;//链表结构struct ListNode{ int m_nValue; ListNode* m_pNext;};//创建一个链表结点ListNode* CreateListNode(int value){ ListNode *pNode=new ListNode(); pNode->m_nValue=value; pNode->m_pNext=NULL; return pNode;}//遍历链表中的所有结点void PrintList(ListNode* pHead){ ListNode *pNode=pHead; while(pNode!=NULL) { cout<
m_nValue<<" "; pNode=pNode->m_pNext; } cout<
m_pNext=pNext; }}void DeleteNode(ListNode** pListHead,ListNode* pToBeDeleted){ 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; }}void main(){ //创建结点 ListNode* pNode1=CreateListNode(1);//创建一个结点 ListNode* pNode2=CreateListNode(2);//创建一个结点 ListNode* pNode3=CreateListNode(3);//创建一个结点 ListNode* pNode4=CreateListNode(4);//创建一个结点 ListNode* pNode5=CreateListNode(5);//创建一个结点 ListNode* pNode6=CreateListNode(6);//创建一个结点 ListNode* pNode7=CreateListNode(7);//创建一个结点 //连接结点 ConnectListNode(pNode1,pNode2);//连接两个结点 ConnectListNode(pNode2,pNode3);//连接两个结点 ConnectListNode(pNode3,pNode4);//连接两个结点 ConnectListNode(pNode4,pNode5);//连接两个结点 ConnectListNode(pNode5,pNode6);//连接两个结点 ConnectListNode(pNode6,pNode7);//连接两个结点 //打印链表 PrintList(pNode1);//打印 //删除结点 DeleteNode(&pNode1,pNode3); //打印链表 PrintList(pNode1);//打印 system("pause");}

输出结果:

1 2 3 4 5 6 7

1 2 4 5 6 7

 

转载地址:http://pptkm.baihongyu.com/

你可能感兴趣的文章
游戏开发中的人工智能
查看>>
Ubuntu 安装BCM 43142无线网卡驱动
查看>>
iOS 疑难杂症 — — UIButton 点击卡顿/延迟
查看>>
免费 官方的ASP.NET MVC电子书-Professional ASP.NET MVC 1.0
查看>>
PL/SQL DEVELOPER
查看>>
SqlServer2005通过出生日期算年龄函数
查看>>
hdu3496(二维背包)
查看>>
centos7安装部署mysql5.7服务器
查看>>
华为实习日记——第三天
查看>>
LinuxThread VS NPTL
查看>>
谈一谈可能用到数据持久化的地方
查看>>
操作表单域中的value值
查看>>
python读取文件中的字典
查看>>
usaco Superprime Rib 搜索
查看>>
neo4j
查看>>
Least Common Ancestors
查看>>
Oracle数据库 之 使用DBLink访问时,提示ORA-01017
查看>>
「学习总结-Haskell-4」Haskell数据类型
查看>>
接口抽取及依赖版本统一介绍
查看>>
Andriod开发学习笔记
查看>>