剑指offer 面试题13:在O(1)时间删除链表结点(C++版)
2017-04-11 21:49
459 查看
题目:给订单想链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。
思路分析:
在链表中删除一个节点,最常用的方法是从链表的头结点开始,顺序遍历查找要删除的结点,并在链表中删除该结点。
之所以要从头开始查找,是因为要得到将被删除的结点的前一个结点。在单向链表中,结点中没有指向前一个结点的指针,所以只能从链表的头结点开始查找。但是由于顺序查找,时间复杂度为O(N).
在单链表中,我们可以很方便的得到要删除的结点的下一个结点。所以我们可以把把下一个结点的内容复制到要删除的结点,然后删除下一个结点,其实就是相当于删除了最初想要删除的结点。这样时间复杂度为O(1).
但是要特殊考虑删除尾结点的情况和链表只有一个结点,要删除该唯一结点的情况:只有尾结点的时候只能遍历得到该结点的前一个结点,进行删除操作;只有一个结点的时候,删除后返回NULL。
代码:
测试用例:
1、功能测试:
从有多个结点的链表的中间删除一个结点
从有多个结点的链表中删除头结点
从有多个结点的链表中删除尾结点
从只有一个结点的链表中删除唯一的结点
2、特殊输入测试:
指向链表头结点指针的为NULL指针
指向要删除结点的指针为NULL指针
思路分析:
在链表中删除一个节点,最常用的方法是从链表的头结点开始,顺序遍历查找要删除的结点,并在链表中删除该结点。
之所以要从头开始查找,是因为要得到将被删除的结点的前一个结点。在单向链表中,结点中没有指向前一个结点的指针,所以只能从链表的头结点开始查找。但是由于顺序查找,时间复杂度为O(N).
在单链表中,我们可以很方便的得到要删除的结点的下一个结点。所以我们可以把把下一个结点的内容复制到要删除的结点,然后删除下一个结点,其实就是相当于删除了最初想要删除的结点。这样时间复杂度为O(1).
但是要特殊考虑删除尾结点的情况和链表只有一个结点,要删除该唯一结点的情况:只有尾结点的时候只能遍历得到该结点的前一个结点,进行删除操作;只有一个结点的时候,删除后返回NULL。
代码:
#include <iostream> using namespace std; struct ListNode{ int val; ListNode *next; ListNode(int x): val(x), next(NULL) {} }; ListNode* DeleteNode( ListNode *head, ListNode *del){//要删除的结点为del if(!head || !del) return NULL; if(!del -> next){//要删除的是尾结点 if(head == del)//只有一个节点 return NULL; else{//不止一个节点 ListNode *p = head; while(p -> next != del){ p = p -> next; } p -> next = del -> next;//del -> next也就是null delete del; del = NULL; return head; } } //要删除的不是尾结点 ListNode *delnext = del -> next; del -> val = delnext -> val; del -> next = delnext -> next;//删除的结点变为delnext delete delnext;//释放指针指向的内存 delnext = NULL;//将指针赋为null,防止变成野指针 return head; } ListNode *createList() { ListNode *dummy_head = new ListNode(-1); //或者ListNode dummy_head(-1); 下面 p= &dummy_head; if(dummy_head == NULL) return NULL; ListNode *p = dummy_head; while(true){ int data; cin >> data; if(data == -1) break; ListNode *node = new ListNode(data); p -> next = node; p = p -> next; } return dummy_head -> next; } ListNode *printList(ListNode* head){ ListNode * p; p = head; while(p){ cout << p -> val << endl; p = p -> next; } return head; } int main(){ ListNode *head = NULL; head = createList(); printList(head); head = DeleteNode(head, head -> next -> next -> next); //head = DeleteNode(head, head -> next -> next ); //head = DeleteNode(head, head -> next ); //head = DeleteNode(NULL, NULL); printList(head); return 0; }
测试用例:
1、功能测试:
从有多个结点的链表的中间删除一个结点
从有多个结点的链表中删除头结点
从有多个结点的链表中删除尾结点
从只有一个结点的链表中删除唯一的结点
2、特殊输入测试:
指向链表头结点指针的为NULL指针
指向要删除结点的指针为NULL指针
相关文章推荐
- 剑指offer 面试题13 在o(1)时间删除链表结点
- 《剑指offer》面试题13:在O(1)时间删除链表结点
- 剑指offer——面试题13:在O(1)时间删除链表结点
- 《剑指offer》(面试题13):在O(1)时间删除链表结点
- 剑指Offer:面试题13——在O(1)时间删除链表结点
- (剑指Offer)面试题13:在O(1)时间内删除链表结点
- 剑指Offer之面试题13:在O(1)时间删除链表结点
- 剑指Offer系列-面试题13:在O(1)时间删除链表结点
- 《剑指offer》面试题57 删除链表中重复的结点 C++ 实现 以及 错误总结 (指针问题)!!
- 面试题13:在O(1)时间删除链表结点
- 剑指offer面试题13——在O(1)时间删除链表结点
- 剑指Offer----面试题13:在O(1)时间删除链表结点
- 【剑指Offer学习】【面试题13 :在O(1)时间删除链表结点】
- 剑指offer-面试题13-在O(1)时间删除链表结点
- 【剑指offer】面试题13、在 O(1)时间上删除链表结点
- 面试题13:在O(1)时间删除链表结点
- 剑指offer 面试题13—在O(1)时间删除链表节点
- 面试题13 在O(1)时间删除链表结点
- 剑指offer--面试题13:在O(1)时间删除链表结点--Java实现
- [剑指offer][面试题13]在O(1)时间删除链表结点