typedef
int
ElementType
;
//链表中的数据类型,修改此处,则可以改变数据类型
struct
Node
;
typedef
struct
Node
*
PtrToNode
;
typedef
PtrToNode
List
;
//此句和下句只是为了程序可读性
typedef
PtrToNode
Position
;
struct
Node
{
ElementType
Element
;
Position
Next
;
};
//测试空表
int
IsEmpty
(
List
L
)
//L是表头
{
return
L
->
Next
==
NULL
;
//不仅要明白算法原理,最好有一种好的实现
}
//测试当前位置是否是链表末尾
int
IsLast
(
Position
P
)
//P是当前位置
{
return
P
->
Next
==
NULL
;
}
//Find函数
Position
Find
(
ElementType
X
,
List
L
)
//根据元素查找其所在位置
{
Position
P
;
P
=
L
->
Next
;
//从第一个元素开始找,L是表头,L->Next才是第一个元素
while
(
P
!=
NULL
&&
P
->
Element
!=
X
)
//&&运算符的作用
{
P
=
P
->
Next
;
//比较下一个元素
}
return
P
;
}
//删除元素X,只删除第一次出现的X,若不存在X,则什么都不做
void
Delete
(
ElementType
X
,
List
L
)
{
Position
P,
Temp
;
P
=
FindPrevious
(
X
,
L
);
if
(
!
IsLast
(
P
))
{
Temp
=
P
->
Next
;
//Temp用于记录要删除的元素地址
P
->
Next
=
Temp
->
Next
;
free
(
Temp
);
}
}
//查找元素X的前一个位置,多与插入与删除一起使用
Position
FindPrevious
(
ElementType
X
,
List
L
)
{
Position
P
;
P
=
L
;
//头结点的使用,避免了第一个元素是特殊的情况
while
(
P
->
Next
!=
NULL
&&
P
->
Next
->
Element
!=
X
)
//有的时候总会迷糊,但画个图会更好理解
{
//若找到则返回前一节点,否则返回最后节点
P
=
P
->
Next
;
//最后节点不是合法的前一节点,因为它后边没有节点
}
return
P
;
}
//在位置P后插入元素X
void
Insert
(
ElementType
X
,
Position
P
)
{
Position
Temp
;
Temp
=
malloc
(
sizeof
(
struct
Node
));
//申请内存注意不要使用指针
if
(
Temp
==
NULL
)
//申请内存时,应检查最后是否申请成功了
printf
(
"Out of space"
);
Temp
->
Element
=
X
;
//此三步逻辑要搞清,画图更容易理解
Temp
->
Next
=
P
->
Next
;
P
->
Next
=
Temp
;
}
//删除链表
void
DeleteList
(
List
L
)
{
Position
P
,
Temp
;
P
=
L
->
Next
;
//循环删除链表
L
->
Next
=
NULL
;
//表为空表
while
(
P
!=
NULL
)
{
Temp
=
P
->
Next
;
//指向下一个要删除的元素
free
(
P
);
//释放内存
P
=
Temp
;
//释放后,P指向的地址已经被清空了,所以P要重新赋值,指向下一个元素
}
}