单链表插入删除操作的时间复杂度

单链表相比数组的优势在于插入删除元素快,不需要移动大量的元素,只需要改变指针的指向,那么插入删除操作的时间复杂度应该是O(1),但是这是不对的,应该分情况讨论。

单链表结构体声明:

typedefstruct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

O(n)的情况

  1. 一个已知头结点的链表(假设足够长),删除第index个元素。
    首先我们需要从头开始向后遍历,直到找到第index-1个结点,这需要O(n)时间;找到以后,改变指针的指向,这需要O(1)的时间。时间复杂度为O(n)。
LinkListhead;
LinkListp=head;
inti=0;
while(p&&i<=index-2)//找到第index-1个结点退出
{
    p=p->next;
    i++;
}
LinkListq=p->next;//q是第index个节点,即要删除的节点
p->next=q->next;//转移指针
free(q);//释放内存<pre name="code" class="cpp">LinkListnewnode=(LinkList)malloc(sizeof(LNode));
newnode->data=newdata;
newnode->next=node->next;
node->next=newnode;
q=NULL;//指向空指针

2.一个已知头结点的链表(假设足够长),在第index个元素前插入一个元素。
首先我们需要从头开始向后遍历,直到找到第index-1个结点,这需要O(n)时间;找到以后,创建新节点,改变指针的指向,这需要O(1)的时间。时间复杂度为O(n)。

LinkList head;
LinkList p=head;
int i=0;
while(p&&i<=index-2)
{
   p=p->next;
    i++;
}
LinkList newnode=(LinkList)malloc(sizeof(LNode));
newnode->data=newdata;
newnode->next=p->next;
p->next=newnode;

O(1)的情况
1.) 一个已知头结点的链表(假设足够长),删除某结点,且告诉你该元素的地址node(struct LNode*类型)。
由于这是单链表,我们无法获取node前一个节点的地址,因此好像不能删除这个结点。但是在我们看来,是否删除这个节点只是看这个节点的data值是否还存在于链表中,因此,我们可以让链表看起来删除了node,实则删除了结点node->next.

LinkListnode1=node->next;
node->data=node1->data;//移交元素
node->next=node1->next;//移交指针
free(node2);//释放目标删除结点后一个节点的内存
node2=NULL;//置空指针

看似删除node结点,实际上node->next成了真正的牺牲品。上述操作在O(1)内完成。
2.) 一个已知头结点的链表(假设足够长),在某结点后面插入新节点,大小为newdata,且告诉你该结点的地址node(struct LNode *类型)。

LinkListnewnode=(LinkList)malloc(sizeof(LNode));
newnode->data=newdata;
newnode->next=node->next;
node->next=newnode;

时间复杂度:O(1)

  • 11
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值