单链表插入删除元素时间复杂度探究

来源:互联网 发布:xp 在端口23连接失败 编辑:程序博客网 时间:2024/05/17 01:51

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

单链表结构体声明:

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

1.        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;

2.        O(1)的情况

1)        一个已知头结点的链表(假设足够长),删除某结点,且告诉你该元素的地址node(struct LNode*类型)。

由于这是单链表,我们无法获取node前一个节点的地址,因此好像不能删除这个结点。但是在我们看来,是否删除这个节点只是看这个节点的data值是否还存在于链表中,因此,我们可以让链表看起来删除了node,实则删除了结点node->next.

代码:

LinkListnode2=node->next;node->data=node2->data;//移交元素node->next=node2->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)时间内完成。

0 0
原创粉丝点击