数据结构与算法分析——c语言描述 练习3.17 答案
老实说我觉得懒惰删除很坑,如何坑呢?坑在代码的实现,除了删除的函数其他都要麻烦很多。首先要再定义一个listRecord来储存链表的总数据,其次同样的函数要实现2种。例如advance函数,是该返回没有删除的下一个呢还是简单粗暴的返回下一个。链表的函数实现当然是要返回后者,而用户想要的是前者。所以你得实现两遍,而且还要想函数名字。麻烦的不得了,所以我只随随便便实现就算了。
list.h
typedef int ElementType; #ifndef _List_H #define _List_H struct Node; typedef struct Node *PtrToNode; struct ListRecord; typedef struct ListRecord *List; typedef PtrToNode Position; List CreatList(); List MakeEmpty(List L); int IsEmpty(List L); int IsLast(Position P, List L); Position Find(ElementType X, List L); void Delete(ElementType X, List L); Position FindPrevious(ElementType X, List L); void Insert(ElementType X, List L, Position P); void DeleteList(List L); Position Header(List L); Position First(List L); Position Advance(Position P); ElementType Retrieve(Position P); #endif
list.c
#include"list.h" #include<stdlib.h> #include"fatal.h" struct Node { ElementType Element; int isDeleted; Position Next; }; struct ListRecord { PtrToNode headNode; int lazyDelNum; int allNum; }; static void Check_ClearLazyDel(List l) { if (l->allNum / 2 < l->lazyDelNum) { Position p = l->headNode; while (p->Next != NULL) { if (p->Next->isDeleted == 1) { Position TmpCell = p->Next; p->Next = TmpCell->Next; free(TmpCell); l->allNum--; l->lazyDelNum--; } p = p->Next; } } } static void lazyDeletion(ElementType X, List L) { Position P = Find(X, L); if (P) { P->isDeleted = 1; L->lazyDelNum++; } } List CreatList() { List l = malloc(sizeof(struct ListRecord)); if (l == NULL) Error("out of memory"); l->headNode = malloc(sizeof(struct Node)); l->headNode->Next = NULL; l->lazyDelNum = 0; l->allNum = 1; return l; } List MakeEmpty(List L) { if (L != NULL) DeleteList(L); L->allNum = 0; L->lazyDelNum = 0; return L; } int IsEmpty(List L) { return L->headNode->Next == NULL; } int IsLast(Position P, List L) { return P->Next == NULL; } Position Find(ElementType X, List L) { Check_ClearLazyDel(L); Position P; P = L->headNode->Next; while (1) { while (P != NULL &&P->Element != X) { P = P->Next; } if (P == NULL) return NULL; else if (P->isDeleted == 0) return P; else P = P->Next; } } void Delete(ElementType X, List L) { Check_ClearLazyDel(L); lazyDeletion(X, L); } Position FindPrevious(ElementType X, List L) { Check_ClearLazyDel(L); Position P; P = L->headNode; while (P->Next != NULL&&P->Next->Element != X) P = P->Next; return P; } void Insert(ElementType X, List L, Position P) { Check_ClearLazyDel(L); Position tmpCell; tmpCell = malloc(sizeof(struct Node)); if (tmpCell == NULL) FatalError("Out of space!!"); tmpCell->Element = X; tmpCell->isDeleted = 0; tmpCell->Next = P->Next; P->Next = tmpCell; L->allNum++; } void DeleteList(List L) { Position p; p = L->headNode->Next; L->headNode->Next = NULL; while (p != NULL) { Position tmp; tmp = p->Next; free(p); p = tmp; } } Position Header(List L) { return L->headNode; } Position First(List L) { return Advance(L->headNode); } Position Advance(Position P) { Position temp = P->Next; if (temp != NULL && temp->isDeleted == 1) { while (1) { temp = temp->Next; if (temp == NULL) return NULL; else if (temp->isDeleted == 0) return temp; } } return temp; } ElementType Retrieve(Position P) { return P->Element; }
#include"list.h" #include<stdio.h> struct ListRecord { PtrToNode headNode; int lazyDelNum; int allNum; }; int main() { List l = CreatList(); for (int i = 0; i < 1208; i++) Insert(i, l, l->headNode); Position p = Advance(l->headNode); for (int i = 1207; i > 1199; i--) Delete(i, l); printf("%p\n", Find(11, l)); printf("%d\n", l->allNum); }