问题描述:
给出单链表头指针以及要删除节点的地址,要求写代码删除这个节点,并且时间复杂度为O(1),如何实现?
分析:
(1) 应变能力
(2) 对时间复杂度的理解
平常思路:
prev->next = temp->next;
free(temp);
但是该思路的时间复杂度为O(n)
解题:
不能从phead开始找,入口在所要删除的节点的地址
(1) 将temp后面的节点的数据拷贝到当前temp处,删除最后一个节点空间
(2) 最后一个节点没有下一个节点时,只能采用遍历的方法。
程序代码如下:
#include <stdio.h> #include <stdlib.h> typedef struct node { int data; struct node * next; }Node; //获取链表之前先插入 Node * get_link(int length, int local, Node **plocal) { Node *temp = NULL; Node *phead = NULL; Node *tail = NULL; int i; //创建单链表 for (i = 0; i < length; i++) { temp = (Node *)malloc(sizeof(Node)); temp->next = NULL; temp->data = length - i; if (phead == NULL) { tail = temp; } if (local == length - i) //要删除的节点地址 { *plocal = temp; } temp->next = phead; phead = temp; } return phead; } void link_print(Node *temp) { while (temp != NULL) { printf("%d\t",temp->data); temp = temp->next; } printf("\n"); } Node * del_node(Node* phead, Node* local) { if (phead == NULL || local == NULL) { printf("arg error\n"); return NULL; } //(1) 最后一个节点 if (local->next == NULL) { if(phead == local) { free(local); return NULL; } Node * prev = phead; while (prev != NULL && prev->next != NULL) { if (prev->next == local) { prev->next = prev->next->next; free(local); return phead; } prev = prev->next; } } else { Node * temp = local->next; //temp指向待删除节点的下一个节点 local->data = local->next->data; //待删除节点的数据保存为下一个节点的数据 local->next = local->next->next; //将下一个节点的地址指向下下一个 free(temp); //删除下一个节点 return phead; } } int main() { Node * phead = NULL; int local = 0; int number = 0; scanf("%d",&number); //链表的节点数 scanf("%d",&local); //要删除的节点 if (number < local || local <= 0 || number <= 0) { printf("number MUST >= local, and MUST be positive integer\n"); exit(EXIT_FAILURE); } Node* plocal = NULL; phead = get_link(number,local,&plocal); link_print(phead); printf("删除数据:%d\n",plocal->data); phead = del_node(phead,plocal); link_print(phead); return 0; }
删除链表节点
最新推荐文章于 2021-08-09 11:48:30 发布