初始化之前,先进行宏定义和类型定义:
#define OK 1
#define ERROR 0
typedef int Status;
typedef int ElemType;
typedef struct LNode{
ElemType data;
LNode *next;
}LNode,*LinkList;
初始化:
StatusInitList(LinkList L)
{
L = (LNode *)malloc(sizeof(LNode));
if (!L)
return ERROR;
L->next = NULL;
return OK;
}
思想:初始化的目的是为了给链表L的头结点分配空间,if()判断分配是否成功,并将链表头结点指针域设置为NULL。
取值:
Status GetElem(LinkList L, int i,ElemType *e)
{
int j = 1;
LinkList p;
p = L->next;
while (p&&j < i)
{
p = p->next;
j++;
}
if (!p || j>i)
return ERROR;
*e = p->data;
return OK;
}
思想:声明指针p,并使p指向首元节点。判断p指向的结点是否存在,并且是否已经指向所要取值的结点,若p指向所要取值的结点将该节点的data数据赋值给*e,否则p顺着next指向下个结点。
插入:
Status ListInsert(LinkList L, int i, ElemType e)
{
LinkList p,s;
int j=0;
p = L;
while (p&&(j < i-1))
{
p = p->next;
j++;
}
if (!p || j>i - 1)
return ERROR;
s = (LNode *)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
思想:找到所要插入结点的位置p,生成一个新的结点*s,将s的指针域指向p的下一个结点,将p的指针域指向s。
删除:
Status ListDelete(LinkList L, int i)
{
LinkList p,q;
int j = 0;
p = L;
while (p && (j < i-1))
{
p = p->next;
j++;
}
if (!p || (j>i-1))
return ERROR;
q = p->next;
p->next = q->next;
free(q);
return OK;
}
思想:找到要删除结点,并让p指向向该节点,找到后把q指向p的下一个结点,将p的指针域指向q的下一个结点,释放q结点。
加入main()测试:
intmain(void)
{
int n, i;
LNode L;
ElemType e, *p;
p = &e;
printf("1.初始化\n2.取值\n3.查找\n4.插入\n5.删除\n6.退出\n");
while (1)
{
printf("请选择:");
scanf("%d", &n);
switch (n)
{
case 1:
if (InitList(&L) == OK)
printf("初始化成功!\n");
else
printf("初始化失败!\n");
break;
case 2:
printf("请输入你要取值的序号:");
scanf("%d", &i);
if (GetElem(&L, i, p) == OK)
printf("该值为:%d\n",*p);
else
printf("取值失败!\n");
break;
case 3:
printf("输入你要查找的值:");
scanf("%d", &e);
printf("你要查找的值的地址为:%d\n",LocateElem(&L, e));
break;
case 4:
printf("请输入插入的位置和数据:");
scanf("%d %d", &i, &e);
if (ListInsert(&L, i, e) == OK)
printf("插入成功!\n");
else
printf("插入失败!\n");
break;
case 5:
printf("请输入要删除的结点的序号:");
scanf("%d", &i);
if (ListDelete(&L, i) == OK)
printf("删除成功!\n");
else
printf("删除失败!\n");
break;
case 6:
exit(0);
}
}
return 0;
}
现在就可以对链表进行操作了。
关于单链表创建,存在两种方法:前插法和后插法。
前插法:
void CreateList_H(LinkList L, int n)
{
LinkList p;
int i;
for (i = 0; i < n; i++)
{
p = (LNode *)malloc(sizeof(LNode));
scanf("%d", &p->data);
p->next = L->next;
L->next = p;
}
}
思想:生成一个新结点*p并将元素赋值到*p指向的数据域。将新结点插到头结点之后。
后插法:
void CreateList_R(LinkList L, int n)
{
LinkList p,r;
int i;
L->next = NULL;
r = L;
for (i = 0; i < n; i++)
{
p = (LNode *)malloc(sizeof(LNode));
scanf("%d", &p->data);
p->next = NULL;
r->next = p;
r = p;
}
}
思想:让r指针指向链表最后一个结点,每一次插入都分配内存,让p指向该区域。让p指针域设置为NULL,将r指针域指向p,最后将指针r指向p。
测试用main():
int main(void)
{
LNode L;
ElemType e, *p;
int n, i;
p = &e;
printf("输入你要创建的长度:");
scanf("%d", &n);
CreateList_R(&L,n);
while (1)
{
printf("1.取值\n2.退出\n");
scanf("%d", &n);
if (n == 1)
{
printf("输入你要取值的序号:");
scanf("%d", &i);
if (GetElem(&L, i,p) == OK)
{
printf("该值为:%d\n",e);
}
else
printf("查找失败!\n");
}
else
exit(0);
}
return 0;
}