一、题目描述
给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。
二、解题思路
1)当删除结点不是尾结点也不是头结点时把该结点下一个结点的内容复制到这个结点,删除下一个结点 -- 实现O(1)
2)当该链表只有一个结点时删除此结点,并把链表头结点置NULL -- O(1)
3)当删除的结点是尾结点时(链表不止一个结点)从头到尾遍历,找到该结点的上一个结点,删除该节点 -- 复杂度O(n)
总的复杂度
[ (n-1)*O(1) + O(n) ] / n = O(1)
【!注意】
此算法的前提是基于待删除的结点确实存在链表中,否则需要花费O(n)的时间去查找。
这点需要跟面试官说明
三、解题算法
/*************************************************************
Author:tmw
date:2018-6-30
**************************************************************/
#include <stdio.h>
#include <stdlib.h>
typedef struct ListNode
{
int data;
struct ListNode* next;
}ListNode;
/**
* 注:本代码未经测试,看逻辑就好
*/
void delete_node( ListNode** head, ListNode* node )
{
/**入参判断**/
if( !head || !node) return;
/**
如果待删除的结点不是尾结点:
把该结点下一个结点的内容复制到这个结点,删除下一个结点 -- 实现O(1)
**/
if( node->next != NULL )
{
node->data = node->next->data;
node->next = node->next->next;
free(node->next);
}
/**如果待删除的结点是头结点且链表只有一个结点 -- O(1)**/
else if( *head == node ) //隐含 node->next==NULL
{
*head = NULL;
free(node);
}
/**如果待删除的结点是尾结点,顺序查找 -- O(n)**/
else
{
ListNode* p = *head;
while( p->next != node )
p = p->next;
p->next = NULL;
free(node);
free(p);
}
}
梦想还是要有的,万一实现了呢~~~ヾ(◍°∇°◍)ノ゙~~~~