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

单链表相比数组的优势在于插入删除元素快,不需要移动大量的元素,只需要改变指针的指向,那么插入删除操作的时间复杂度应该是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);//释放内存
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)

你可能感兴趣的:(数据结构,单链表删除操作的时间复杂度,单链表插入操作的时间复杂度,单链表插入删除操作的时间复杂度,单链表删除插入操作的时间复杂度)