您的位置:首页 > 编程语言 > C语言/C++

剑指offer 面试题13:在O(1)时间删除链表结点(C++版)

2017-04-11 21:49 459 查看
题目:给订单想链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。

思路分析:

在链表中删除一个节点,最常用的方法是从链表的头结点开始,顺序遍历查找要删除的结点,并在链表中删除该结点。

之所以要从头开始查找,是因为要得到将被删除的结点的前一个结点。在单向链表中,结点中没有指向前一个结点的指针,所以只能从链表的头结点开始查找。但是由于顺序查找,时间复杂度为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指针
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  链表 删除结点