在O(1)时间内删除单链表结点

题目:

给定单链表的一个结点的指针,同时该结点不是尾结点,此外没有指向其它任何结点的指针,请在O(1)时间内删除该结点。


思路:分两种情况

1.如果不是尾结点,将要删除的结点的下一个结点的值copy到删除结点,这样只要删除下一个结点即可。

2.如果是尾结点,则遍历删除。


总的时间复杂度为O(1)


代码:

#include <stdio.h>
#include <stdlib.h>
#include <stack>
typedef int elem;
typedef struct node
{
   elem data;
   struct node *next;
}LNode, *LINKLIST;

/*删除链表,时间复杂度O(1),p是要删除的结点*/ 
void deleteNode(LINKLIST list, LNode* p) 
{
	LNode* q;
	LNode* next;
	LNode* node = list;
	if (p->next != NULL)
	{
		/*讲下一个结点的值copy过来*/ 
		q = p->next;
		p->data = q->data;
		/*讲下一个结点删除即可,用p替换下一个结点*/ 
		p->next = q->next;
		/*释放内存*/ 
		free(q);
		q = NULL;
	}
	/*如果为最后一个结点,只能遍历删除*/
	else
	{
		while ((node->next!=NULL) && (node->next!=p))
		{
			node = node->next;
		}
		if (node->next == NULL)
		{
			return;
		}
		/*按照通用的方式删除*/ 
		next = p->next;
		node->next = next;
		free(p);
		p = NULL;
	} 
}

/*采用尾插法,创建单链表*/
void createList(LINKLIST list, elem data)
{
    LNode* p = list;
    LNode* newNode;
    while (p->next != NULL)
    {
        p = p->next;
    }
    newNode = (LNode*)malloc(sizeof(LNode));
    newNode->next = NULL;
    newNode->data = data;
    p->next = newNode;
}
/*打印单链表*/
void printList(LINKLIST list, void(*print)(elem))
{
    LNode* p = list->next;
    while (p != NULL)
    {
         print(p->data);
         p = p->next;
    }
    printf("\n");
}
/*打印结点值*/
void printElem(elem data)
{
    printf("%d\t", data);
}
int main()
{
   LINKLIST list = NULL;
   elem data[] = {1,2,3,4,5,6};
   int i;
   list = (LINKLIST)malloc(sizeof(LNode));
   list->next = NULL;
   list->data = 0;
   for (i=0; i<6; i++)
   {
        createList(list, data[i]);
   }
   printList(list, printElem);
   deleteNode(list, list->next->next);
   printList(list, printElem);
   deleteNode(list, list->next);
   printList(list, printElem);
   deleteNode(list, list->next);
   deleteNode(list, list->next);
   deleteNode(list, list->next);
   printList(list, printElem);
   deleteNode(list, list->next);
   printList(list, printElem);
   return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值