剑指offer十五:在O(1)时间删除链表结点
结点定义如下:
typedef struct linklist
{
int data;
linklist* next;
}node, *pnode;
在头部添加结点,生成一个一定长度的链表:
pnode addNodeToHead(pnode head, pnode newnode)
{
if (head == NULL)
{
newnode->next = NULL;
head = newnode;
return head;
}
newnode->next = head;
head = newnode;
return head;
}
通过循环遍历找到待删除结点的方法,复杂度为O(n):
pnode deleteNode(pnode head, pnode beDeleted)
{
if (head == NULL || beDeleted == NULL)
return NULL;
pnode temp = head;
//被删除的结点为头结点
if (temp->data == beDeleted->data)
{
temp = temp->next;
return head;
}
while (temp->next->data != beDeleted->data)
{
temp = temp->next;
if (temp->next == NULL)//被删除的结点不在该链表中
return NULL;
}
pnode a = temp->next;
temp->next = a->next;
free(a);
return head;
}
通过赋值覆盖间接删除该结点,复杂度为O(1):
pnode DeleteNodeEffect(pnode head, pnode beDelected)
{
pnode temp = head;
if (temp == NULL || beDelected == NULL)
return NULL;
//链表中只有一个结点
if (temp->next == NULL)
{
delete temp;
temp = NULL;
}
//被删除结点不在尾部
if (beDelected->next != NULL)
{
pnode Dnext = beDelected->next;
beDelected->data = Dnext->data;
beDelected->next = Dnext->next;
delete Dnext;
}
//被删除结点在尾部,就需要顺序遍历
if (beDelected->next == NULL)
{
pnode temp = head;
while (temp->next != beDelected)
{
temp = temp->next;
}
temp->next = NULL;
delete beDelected;
}
return head;
}
完整代码:
#include<iostream>
using namespace std;
//定义链表结点
typedef struct linklist
{
int data;
linklist* next;
}node, *pnode;
//在头部添加结点
pnode addNodeToHead(pnode head, pnode newnode)
{
if (head == NULL)
{
newnode->next = NULL;
head = newnode;
return head;
}
newnode->next = head;
head = newnode;
return head;
}
//从前往后顺序遍历找到待删除结点算法
pnode deleteNode(pnode head, pnode beDeleted)
{
if (head == NULL || beDeleted == NULL)
return NULL;
pnode temp = head;
if (temp->data == beDeleted->data)
{
head = head->next;
return head;
}
while (temp->next->data != beDeleted->data)
{
temp = temp->next;
if (temp->next == NULL)
return NULL;
}
pnode a = temp->next;
temp->next = a->next;
free(a);
return head;
}
//不需要遍历待删除结点前面的结点,用待删除结点后的结点覆盖待删除结点
pnode DeleteNodeEffect(pnode head, pnode beDelected)
{
pnode temp = head;
if (temp == NULL || beDelected == NULL)
return NULL;
//链表中只有一个结点
if (temp->next == NULL)
{
delete temp;
temp = NULL;
}
//被删除结点不在尾部
if (beDelected->next != NULL)
{
pnode Dnext = beDelected->next;
beDelected->data = Dnext->data;
beDelected->next = Dnext->next;
delete Dnext;
}
//被删除结点在尾部,就需要顺序遍历
if (beDelected->next == NULL)
{
pnode temp = head;
while (temp->next != beDelected)
{
temp = temp->next;
}
temp->next = NULL;
delete beDelected;
}
return head;
}
//遍历链表输出
void output(pnode head)
{
pnode temp = head;
while (temp != NULL)
{
cout << temp->data << '\t';
temp = temp->next;
}
}
int main()
{
int a[] = { 1,2,3,4,5,6,7,8,9 };
pnode head = NULL;
for (int i = 0; i < 9; i++)
{
pnode newnode = new node();
newnode->data = a[i];
head = addNodeToHead(head, newnode);
}
output(head);
cout<<endl;
pnode beDeleted = new node();
beDeleted = head->next->next;
//head = deleteNode(head, beDeleted);
head = DeleteNodeEffect(head, beDeleted);
output(head);
}