剑指Offer系列---(16)在O(1)时间删除链表结点
2015-09-10 11:34
387 查看
1.题目描述:
给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。链表结点与函数的定义如下:
struct ListNode
{
int m_nValue;
ListNode* m_pNext;
};
void DeleteNode(ListNode** pListHead,ListNode* pToBeDeleted);
2.分析:
1)在单向链表中删除一个结点,最常规的做法无疑是从链表的头结点开始,顺序遍历查找要删除的结点,并在链表中删除该节点。
2)如果我们把下一个结点的内容复制到需要删除的结点上覆盖原来的内容,再把下一个结点删除,那就相当于把当前结点删除了。
3)此方法的前提是结点存在于链表内,删除最后一个结点时比较特殊。
3.源代码:
给定单向链表的头指针和一个结点指针,定义一个函数在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; }
相关文章推荐
- JS数据类型之RegExp类型
- JavaScript 点击事件小节
- Javascript跨浏览器事件处理
- 获取html网页的内容
- java中用jquery AutoComplete 实现自动补全(一)简单小例子
- document.getElementById为空或不是对象的解决方法
- 原生JS实现仿淘宝网左侧商品分类菜单效果代码
- 可以直接拿来用的css表格样式
- 页面不够高,尾部在底部样式
- 【leetcode】Count Complete Tree Nodes -C++
- javaScript的运行机制?
- select下拉框与层之冲突
- javascript的trim()函数的实现
- IE怎么bootstrap怎么居中兼容
- gulp及gulp说明
- jQuery document window load ready 区别详解
- JavaScript版几种常见排序算法
- Javascript 的 Attribute 方法
- Angular简单例子
- web 中重新播放css 动画