先上代码:
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#include<stdlib.h>
typedef int Status
typedef int ElemType
typedef struct Node
{
ElemType data;
struct Node *next;
}Node,*LinkList;
Status GetElem(LinkList L,int i,ElemType *e)
{
int j;
LinkList p;
p=L->next;
j=1;
while(p && j<i) //检查p是否为空指针以及p是否到达i结点
{
p=p->next;
++j;
}
if(!p || j>i) //包含了p为空和非法的i输入
{
return ERROR;
}
*e=p->data;
return OK;
}
Status ListInsert(LinkList *L,int i,ElemType e) //注意这里L并不直接指向Node,是*L直接指向Node
{
int j;
LinkList p,s;
p->*L; //p代表了头结点的指针域
j=1;
while(p && j<i)
{
p=p->next;
++j;
}
if(!p || j>i)
return ERROR;
s=(LinkList)malloc(sizeof(Node));
s->data=e;
s->next=p->next;
p->next=s;
return OK;
}
Status ListDelete(LinkList *L,int i,ElemType *e)
{
int j;
LinkList p,q;
p=*L; //p是头结点的指针域,指向第一个结点
j=1;
while(p->next && j<i) //循环结束后p指向第i-1个结点,这里要保证第i个结点不是NULL
{
p=p->next;
++j;
}
if(!(p->next) || j>i)
return ERROR;
q=p->next;
p->next=q->next; //这里考虑进了q是最后一个结点的情况,那么p->next会被赋NULL
*e=q->data;
free(q);
return OK;
}
void CreateListHead(LinkList *L,int n) //在链表头部插入新元素
{
LinkList p;
int i;
srand(time(0)); //初始化随机数种子
*L=(LinkList)malloc(sizeof(Node)); //这个叫作头结点
(*L)->next=NULL;
for(i=0;i<n;i++)
{
p=(LinkList)malloc(sizeof(Node));
p->data=rand()%100+1; //随机生成100以内的数字
p->next=(*L)->next; //在头结点和尾结点中间插入新结点,一共有n个有效结点
(*L)->next=p;
}
}
void CreateListTail(LinkList *L,int n)
{
LinkList p,r;
int i;
srand(time(0));
*L=(LinkList)malloc(sizeof(Node));
r=*L;
for(i=0;i<n;i++)
{
p=(Node*)malloc(sizeof(Node));
p->data=rand()%100+1;
r->next=p;
r=p;
}
r->next=NULL;
}
Status ClearList(LinkList *L)
{
LinkList p,q;
p=(*L)->next;
while(p)
{
q=p->next;
free(p);
p=q;
}
(*L)->next=NULL;
return OK;
}
理解单链表的两个重要问题:
1、LinkList *L这种定义的本质是什么?
答:L是指向结构体Node的指针的指针,结构体Node可以用**L表示,也就是说(**L).data等价于(*L)->data。这里头结点是(**L),(*L)->next是指向第一个非头结点的指针。
2、头结点的意义是什么?
答: