利用单链表数据结构实现一组数据的存储,通过简单的交互实现单链表的增删改查。
//ADT 线性表(List) 链式存储结构 LinkList
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int ElemType;
typedef int Status;
//定义单链表
typedef struct Node
{
ElemType data;
struct Node *next;
} Node;
typedef struct Node *LinkList; //定义结点结构体指针
//初始化单链表
Status InitList(LinkList *L, int *Length)
{
*L = (LinkList)malloc(sizeof(Node)); //创建头结点,用头指针L指向
*Length = 0; //初始化单链表长度为0
if (*L == 0) //创建头结点失败返回EEOR
return ERROR;
else
return OK;
}
//判断单链表是否初始化成功
Status ListEmpty(LinkList L)
{
if (L->next == 0)
return FALSE;
else
return TRUE;
}
//清空单链表
Status ClearList(LinkList *L, int *Length)
{
LinkList p = NULL;
LinkList q = NULL;
p = (*L)->next; //指向第一个结点
if (p == 0)
return ERROR;
else
while (p)
{
q = p->next;
free(p); //释放结点申请的动态内存空间
p = q;
}
(*L)->next = NULL; //将头结点指针域清空
free(*L); //释放头结点
*Length = 0;
return OK;
}
//查询数据元素的个数
Status ListLength(int Length)
{
return Length;
}
//单链表数据元素的输入
Status CreateList(LinkList *L, int *Length)
{
LinkList s = (*L);
printf("请输入一组整型数据:");
while (TRUE)
{
int a = 0;
LinkList p = NULL;
scanf("%d", &a);
char c = getchar();
p = (LinkList)malloc(sizeof(Node));
p->data = a;
s->next = p;
s = p;
p->next = NULL;
*Length = *Length + 1;
if (c == '\n')
break;
}
return OK;
}
//关于单链表的增删改查操作
//单链表的取值,用e将单链表中第i个数据元素的值取出
Status GetElem(LinkList L, int i, ElemType *e, int Length)
{
int j;
LinkList p = L->next;
if (i > Length || p == 0)
return ERROR;
for (j = 1; j < i; j++)
{
p = p->next;
if (p == 0)
return ERROR;
}
*e = p->data;
return OK;
}
//单链表的查询,查询单链表中数据元素的值为e的位序i
Status LocateElem(LinkList L, ElemType e)
{
int i = 0;
LinkList p = L->next;
while (p)
{
i++;
if (p->data == e)
return i;
p = p->next;
}
return ERROR;
}
//单链表的插入,将值为e的数据元素插入到单链表的第i个位置
Status ListInsert(LinkList *L, int i, ElemType e, int *Length)
{
int j;
LinkList p = (*L)->next;
LinkList s = NULL;
if (i > *Length)
return ERROR;
for (j = 1; j < i - 1; j++)
{
p = p->next;
if (p == 0)
return ERROR;
}
s = (LinkList)malloc(sizeof(Node));
s->data = e;
s->next = p->next;
p->next = s;
*Length = *Length + 1;
return OK;
}
//单链表的删除,将单链表第i个数据元素删除,用e返回其值。
Status ListDelete(LinkList *L, int i, ElemType *e, int *Length)
{
int j;
LinkList p = (*L)->next;
LinkList q = NULL;
if (i > *Length)
return ERROR;
for (j = 1; j < i - 1; j++)
{
p = p->next;
if (p == 0)
return ERROR;
}
q = p->next;
p->next = q->next;
*e = q->data;
free(q);
*Length = *Length - 1;
return OK;
}
//单链表主函数
int main()
{
LinkList L = NULL;
ElemType e = 0;
Status i = 0;
int Length = 0;
printf("单链表自动初始化中......\n");
i = InitList(&L, &Length); //初始化单链表
i = ListEmpty(L); //判断单链表是否初始化成功
if (i == 1)
printf("单链表初始化成功,单链表长度为%d\n", Length); //输出初始化结果
else
printf("单链表初始化失败\n");
i = CreateList(&L, &Length);
if (i == 1)
printf("数据元素存储完毕,数据元素个数为%d\n", Length);
while (TRUE) //该循环意在实现交互性。
{
int a;
printf("请选择要进行的操作:\n1:查询单链表数据元素个数\n2:取出相应位序数据元素的值\n3:查询数据元素的值的相应位置\n4:数据元素的插入\n5:数据元素的删除\n6:清空单链表并结束程序\n");
scanf("%d", &a);
switch (a)
{
case 1:
{
int b;
b = ListLength(Length);
printf("单链表数据元素个数为%d\n", b);
break;
}
case 2:
{
int b;
printf("请输入将要取值的位序:");
scanf("%d", &i);
b = GetElem(L, i, &e, Length);
if (b == 0)
printf("将要取值的位序不正确\n");
else
printf("取值成功,值为%d\n", e);
break;
}
case 3:
{
int b;
printf("请输入将要查询的值:");
scanf("%d", &e);
b = LocateElem(L, e);
if (b == 0)
printf("将要查询的值不在顺序表中\n");
else
printf("查询成功,位序为:%d\n", b);
break;
}
case 4:
{
int b;
printf("请输入将要插入的值:");
scanf("%d", &e);
printf("请输入将要插入的位序:");
scanf("%d", &i);
b = ListInsert(&L, i, e, &Length);
if (b == 0)
printf("插入失败\n");
else
printf("插入成功\n");
break;
}
case 5:
{
int b;
printf("请输入将要删除的位序:\n");
scanf("%d", &i);
b = ListDelete(&L, i, &e, &Length);
if (b == 0)
printf("删除失败\n");
else
printf("删除成功,删除的值为%d\n", e);
break;
}
case 6:
{
int b;
b = ClearList(&L, &Length);
if (b == 0)
printf("单链表清空失败\n");
else
printf("单链表清空成功\n");
exit(0);
}
default:
break;
}
}
return 0;
}