Icoding 链表 删除范围内结点
1.题目:
已知线性表中的元素(整数)以值递增有序排列,并以单链表作存储结构。试写一高效算法,删除表中所有大于mink且小于maxk的元素(若表中存在这样的元素),分析你的算法的时间复杂度。
链表结点定义如下:
struct _lnklist{
ElemType data;
struct _lnklist *next;
};
typedef struct _lnklist Node;
typedef struct _lnklist *LinkList;
函数原型如下:
void lnk_del_x2y(LinkList L, ElemType mink, ElemType maxk)
其中L指向链表的头结点。
void lnk_del_x2y(LinkList LA, int mink, int maxk) {
LinkList l = LA->next;
LinkList pre = NULL;
Node *temp_Max = NULL;
Node *temp_Min = NULL;
while (l) {
if (l->next->num > mink && !temp_Min) temp_Min = l;
else if (l->num >= maxk && temp_Max == NULL) {
temp_Max = l;
break;
}
pre = l;
l = l->next;
if (pre->num > mink && pre->num < maxk) free(pre);
}
if (!temp_Min || !temp_Max) {
printf("范围错误");
} else {
temp_Min->next = temp_Max;
}
}
答案:
#include "list.h" // 请不要删除,否则检查不通过
#include <stdio.h>
#include <stdlib.h>
void lnk_del_x2y(LinkList L, ElemType mink, ElemType maxk)
{
LinkList p, pre, s;
p = L->next;
pre = L;
if (p == NULL) {
return 0;
}
while (p) {
if (mink < p->data && p->data < maxk) {
s = p;
p = p->next;
pre->next = p;
free(s);
} else {
p = p->next;
pre = pre->next;
}
}
}
总结
答案的做法是每扫描到一个在删除区间的值,单独删除该节点并释放。
我的做法是找到第一个超过mink之前的那个节点,和第一个超过maxk的节点,首尾相连即可。
同时加上一个判断,并专门设置pre节点用于释放中间要删除的节点空间。