单链表在很多场合下,是线性表的首选存储结构。然而,它也存在这实现某些基本操作,如求线性表的长度时不如顺序存储结构的缺点。另一方面,由于在链表中,结点之间的关系用指针来表示。则数据元素在线性表中的位序的概念已经淡化,而被数据元素在线性链表中的位置所代替,为此,从实际应用角度出发重新定义线性链表及其基本操作。
定义的辅助宏:
#define OK 1
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define NULL 0
#define OVERFLOW -1
typedef int Status;
typedef int ElemType;//假设改进链表中的元素均为整型
改进链表的存储结构定义:
//结点类型
typedef struct LNode{
ElemType data;
struct LNode * next;
}*Link,*Position;
typedef struct{ //链表类型
Link head,tail; //头指针与尾指针
int len; //表长
}LinkList;
分配由p指向的值为e的结点,并返回OK,若分配失败,返回ERROR.
Status MakeNode(Link &p,ElemType e){
//分配由p指向的值为e的结点,并返回OK,若分配失败,返回ERROR
p=(LNode *)malloc(sizeof(LNode));
if(!p)
return ERROR;
p->data=e;
p->next=NULL;
return OK;
}
释放p所指结点.
void FreeNode(Link &p){
//释放p所指结点
free(p);
p=NULL;
}
构造一个空的线性链表L,头尾指针指向头结点.
Status InitList(LinkList &L){
//构造一个空的线性链表L,头尾指针指向头结点
ElemType e;
e=-1; //实际应用中此初始化语句需要修改
if(!MakeNode(L.head,e)) //开辟头结点
return ERROR;
L.tail=L.head;
L.len=0;
return OK;
}
销毁线性表L,L不再存在。
Status DestroyList(LinkList &L){
//销毁线性表L,L不在存在
LNode *p=L.head->next;
while(p){
L.head->next=p->next;//依次释放第一个结点到最后一个结点所占空间
FreeNode(p);
p=L.head->next;
}
FreeNode(L.head);
L.head=NULL;
L.tail=NULL;
L.len=0;
return OK;
}
将线性表L重置成空表,并释放原链表的结点空间.
Status ClearList(LinkList &L){
//将线性表L重置成空表,并释放原链表的结点空间
LNode *p=L.head->next;
while(p) {
L.head->next=p->ne