编写实现使用懒惰删除的标准链表操作的例程

数据结构与算法分析——c语言描述 练习3.17 答案


老实说我觉得懒惰删除很坑,如何坑呢?坑在代码的实现,除了删除的函数其他都要麻烦很多。首先要再定义一个listRecord来储存链表的总数据,其次同样的函数要实现2种。例如advance函数,是该返回没有删除的下一个呢还是简单粗暴的返回下一个。链表的函数实现当然是要返回后者,而用户想要的是前者。所以你得实现两遍,而且还要想函数名字。麻烦的不得了,所以我只随随便便实现就算了。


TheDean网友说应该delete应该调用懒惰删除,而不是同时提供真实删除和懒惰删除的函数。影藏内部实现细节。

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;
}




main.c

#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);
}



你可能感兴趣的:(编写实现使用懒惰删除的标准链表操作的例程)