实验内容
编写程序完成单链表的下列基本操作:
- 建立一个长度为n的单链表。
- 插入新结点。
- 删除某一个结点。
- 打印输出La中的结点元素值。
实验方法
- 数据产生
通过随机数函数获得数据,或通过赋值方法确定数据。 - 线性表的插入与删除
线性表在本次实验中是动态变化,插入、删除元素,为使线性表任保持有序性,必须要找到元素插入或删除的位置。
源代码
/********************
> File Name: ll.c
> Author:Raoby
> School:WUST_EEA_1801班
> Myblog:www.raobee.com
> Mail:1458096930@qq.com
> Created Time: 2020年06月03日 星期三 21时22分23秒
********************/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
typedef struct sNode
{
int data;
struct sNode* next;
}Node;
int creat(Node* head, int length) //创建新链表
{
//根据输入的指针作为头部,创建长度为length,数据为随机数的链表
int i; //计数局部变量
Node* p2,*p1 = head; //局部指针变量
srand((unsigned int)time(NULL));
for (i = 0; i < length; i++)
{
if (p2 = (Node*)malloc(sizeof(Node)))
{
//申请内存成功
p2->data = rand();
p2->next = NULL; //此步此处其实可以忽略,因为循环体中都会赋值
p1->next = p2;
p1 = p2;
}
else
{
//申请内存出现问题,退出循环体,清除已分配的区域并返回-1错误码
break;
}
}
if (i < length)
{
//未达到循环条件便退出,认为是分配内存错误,清除已分配区域
p1 = head->next;
while (p1)
{
p2 = p1->next;
free(p1);
p1 = p2;
}
return -1;
}
p1->next = NULL; //末尾节点指针设为空
return 0; //创建成功
}
int insert(Node* head, int place, int data) //输入插入至第place位,原本place位及之后数据向后移
{
int i;
Node* p2, * p1 = head;
if (place <= 0) //输入数据位置有误
{
return -1;
}
//定位至第place号节点前一位
for (i = 0; i < place-1; i++)
{
if (!p1->next)
{
return -1; //输入数据越界
}
p1 = p1->next;
}
p2 = p1->next;
p1->next = (Node*)malloc(sizeof(Node));
p1->next->next = p2;
p1->next->data = data;
return 0;
}
int delete(Node* head, int place)
{
int i;
Node* p2,*p1 = head;
p2 = p1;
if (place <= 0) //输入数据位置有误
{
return -1;
}
//定位至第place号节点前一位
for (i = 0; i < place; i++)
{
p2 = p1;
p1 = p1->next;
if (!p1) //若p1变为空指针,即输入位置越界,删除失败,返回-1
{
return -1;
}
}
p2->next = p1->next; //被删除节点上节点连接至下节点
free(p1);
return 0;
}
int* show(Node* head, int place) //查询指定节点数据函数,查询成功返回指定节点数据指针
{
int i;
Node* p = head;
if (place <= 0) //输入数据位置有误
{
return NULL;
}
for (i = 0; i < place; i++)
{
p = p->next;
if (!p) //若p变为空指针,即输入位置越界,查询失败,返回空指针
{
return NULL;
}
}
return &(p->data);
}
int change(Node* head, int place, int NewData)
{
int i;
Node* p = head;
if (place <= 0) //输入数据位置有误
{
return -1;
}
for (i = 0; i < place; i++)
{
p = p->next;
if (!p) //若p变为空指针,即输入位置越界,查询失败,返回-1
{
return -1;
}
}
p->data = NewData;
return 0;
}
int main()
{
int choose = 1, length,ret,*pret,input1,input2;
Node* gnode=malloc(sizeof(Node));
printf("请输入要新增的单链表长度,输入非正整数自动退出:");
scanf("%d", &length);
if (length <= 0)
{
printf("运行结束");
return 0;
}
if (ret = creat(gnode, length))
{
//如果返回值不为0会进入此处,即创建链表失败
printf("创建失败!\n可能是内存不足,返回值:%d\n",ret);
return 0;
}
while (choose)
{
system("cls"); //清空屏幕
printf("请输入一个选项\n1.在链表指定位置新增节点\n2.删除指定节点\n3.查看指定位置节点数据\n4.修改指定位置节点数据\n0.退出程序\n请输入:");
scanf("%d", &choose);
switch (choose)
{
case 1:
{
printf("输入要插入的位数与数据,用半角逗号分割,原本此位若有数据会向后移:");
scanf("%d,%d", &input1, &input2);
if (input1 <= 0)
{
printf("输入有误,退出插入\n");
}
else
{
if (ret = insert(gnode, input1, input2))
{
//返回值不为零代表出错
switch (ret)
{
case -1:
{
printf("输入位置越界!\n");
break;
}
default:
{
printf("插入出错,错误码:%d", ret);
}
}
}
else
{
printf("插入成功!\n");
}
}
system("pause");
break;
}
case 2:
{
printf("输入要删除数据位置:");
scanf("%d", &input1);
if (input1 <= 0)
{
printf("输入有误,退出插入\n");
}
else
{
if (ret = delete(gnode, input1))
{
//返回值不为零代表出错
switch (ret)
{
case -1:
{
printf("输入位置越界!\n");
break;
}
default:
{
printf("删除出错,错误码:%d", ret);
}
}
}
else
{
printf("删除数据成功!\n");
}
}
system("pause");
break;
}
case 3:
{
printf("输入要查看节点位置:");
scanf("%d", &input1);
if (input1 <= 0)
{
printf("输入有误,退出插入\n");
}
else
{
if (!(pret = show(gnode, input1)))
{
//返回值为零代表出错
printf("查看数据出错!\n");
}
else
{
printf("第%d位的数据为:%d\n",input1,*pret);
}
}
system("pause");
break;
}
case 4:
{
printf("输入要修改的位数与数据,用半角逗号分割:");
scanf("%d,%d", &input1, &input2);
if (input1 <= 0)
{
printf("输入有误,退出插入\n");
}
else
{
if (ret = change(gnode, input1, input2))
{
//返回值不为零代表出错
switch (ret)
{
case -1:
{
printf("输入位置越界!\n");
break;
}
default:
{
printf("修改出错,错误码:%d", ret);
}
}
}
else
{
printf("修改成功!\n");
}
}
system("pause");
break;
}
}
}
printf("运行结束!\n");
return 0;
}