链表

链表由一系列不必再内存中相连的结构组成,每一个结构都含有表元素和指向该元素后继元的结构的指针。这个是定义,看着比较晕。其实链表就是一个表,表中有两个内容,一个是一些基本元素,另外一个是指针,顺着这个指针,可以找到下一个表。如图所示:


链表分有头结点的链表,和没有头结点的链表,上图是有头结点的链表,没有头结点的链表就是把头部分去掉。即


一般来说带有头结点的链表比较常用,在检查是否空表以及在表头插入结点等方面,带有头结点的链表比较有优势。

链表比较常用的操作主要有检查空表,查找节点,插入节点,删除节点。下面编程实现一下:

0) 先来定义一下头结点:

这要用到先下面1) 中的一些定义

void InitList(List L)
{
	header = (Position) malloc(sizeof(struct Node));
	if(header==NULL)
		FataError("out of space");
	header->Next = NULL;
}

1) 链表的定义以及一些初始声明

typedef struct Node *PtrToNode;
typedef PtrToNode List;
typedef PtrToNode Position;
typedef int ElementType 

struct Node
{
	ElementType Element;
	Position Next;
};

前四行是利用typedef做的一些声明,这里应用typedef的原因主要有两点:(1)是方便以后程序移植或修改,例如当我们需要让链表中存放的是double时,则只需要修改就可以了

typedef double ElementType 
(2) 是能够使程序清晰明确,例如我们看到List就知道这是一个链表指针,这很清晰,其实List等价于 

struct Node *List;
2) 检查空表

int IsEmpty(List L)
{
	return L->Next==NULL;
}
空表就是表的第一个指针指向NULL。

3) 查找结点

Position Find(ElementType X, List L)
{
	Position P;
	P = L->Next;
	while(L!=NULL && L->Element!=X)
		P = P->Next;
	return P;
}
函数返回值是指向我们要查找的结点的指针,我们要查找的结点就是P->Element。需要注意的一个地方就是L!=NULL,L==NULL标志着表的结束,如果没有限定条件L!=NULL,表是要查找过界的。

4) 插入结点

插入结点的步骤如下图(a)所示:

void Insert(ElementType X,List L,Position P)
{
	Position tmp;
	Tmp = malloc(sizeof(struct Node));
	if(tmp==NULL)
		FatalError("Out of Space!");
	Tmp->Element = X;
	Tmp->Next = P->Next;
	P->Next = Tmp;
}



4) 删除结点

删除结点的步骤如上图(b)所示:

在执行删除前,首先我们要找到删除的地方

Position FindPrevious(ElementType X, List L)
{
	Position P;
	P=L;
	while(P->Next!=NULL && P_>Next->Element!=X)
		P=P->Next;
	return p;
}
然后再执行删除操作

void Delete(ElementType X,List L)
{
	Position P,Tmp;
	P = FindPrevious(X,L);
	if(!IsLast(P,L))
	{
		Tmp = P->Next;
		p->Next = Tmp->Next;
		free(Tmp);
	}
}
int IsLast(Position P,List L)
{
	return P->Next==NULL;
}
在进行链表操作的时候最好画出相关的示意图,如上面的插入删除图所示,这样可以避免一些错误。

5) 删除整个链表

删除整个链表就相当于依次释放各个节点也就是我们不断通过malloc函数动态创建的指针,声明指针本身是不占用内存空间的,但是malloc函数是动态分配了内存的,因此当删除链表时,应该用free函数释放这些内存,否则会使内存越来越小最终泄露。

void DeleteList(List L)
{
	Position P,Tmp;
	P = L->Next;	//得到头结点,现在P就相当于Header
	L->Next = NULL; //header指向NULL
	while(P!=NULL)
	{
		Tmp = P->Next;
		free(P);
		P=Tmp;
	}
}
这里面会容易产生一个错误:

while(P!=NULL)
	{
		free(P);
		P=P->Next;
	}
这一部分中,如果free(P)了,那么就没有P了,所以程序也就无法得知P->Next是什么了。











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值