答案:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef int SLTDataType;
typedef struct SListNode {
SLTDataType data;
struct SListNode* next;
}SLTNode;
void PrintSLT(SLTNode* phead) //打印单链表
{
SLTNode* pcur = phead;
while (pcur)
{
printf("%d->", pcur->data);
pcur = pcur->next;
}
printf("NULL\n");
}
SLTNode* SLTBuyNode(SLTDataType x) //创建新结点
{
SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
if (newnode == NULL) //如果创建新结点失败
{
perror("malloc fail!"); //报错原因
exit(1); //结束退出
}
newnode->data = x;
newnode->next = NULL;
return newnode;
}
void SLTPushFront(SLTNode** pphead, SLTDataType x) //头插
{
assert(pphead); //避免传进的二级指针为空
SLTNode* newnode = SLTBuyNode(x);
newnode->next = *pphead; //头插
*pphead = newnode; //新结点为头结点
}
void SLTInsert(SLTNode** pphead, int i , SLTDataType x) //在指定位置之前插入数据
{
assert(pphead && *pphead); //避免传入空的二级指针以及是空链表
assert(i >= 0);
SLTNode* newnode = SLTBuyNode(x);
if (i == 0) //如果是在头结点之前插入
{
SLTPushFront(pphead, x); //调用头插函数
}
else
{
SLTNode* prev = *pphead;
for (int n = 1; n <= i ; n++) //遍历找到i之前的结点位置
{
if (n == i) //插入
{
newnode->next = prev->next;
prev->next = newnode;
}
else //继续遍历
{
prev = prev->next;
}
}
}
}
void SLTErase(SLTNode** pphead, int i) //删除第i个结点
{
assert(pphead && *pphead);
assert(i >= 0);
if (i == 0) //如果要删除头结点
{
SLTNode* next = (*pphead)->next;
free(*pphead);
*pphead = next;
}
else
{
SLTNode* p = *pphead;
while (p->next != NULL && i--) //利用短路特点,使得如果删除最后的NULL失败
{
if (i == 0)
{
SLTNode* next = p->next;
p->next = p->next->next;
free(next);
}
else
{
p = p->next;
}
}
if (i > 0)
{
printf("该结点不存在\n");
}
}
}
void SLTFind1(SLTNode* phead,int i) //查找第i个位置的值
{
assert(phead);
SLTNode* p = phead;
while (i-- && p!=NULL)
{
p = p->next;
}
if (p != NULL)
{
printf("第i个的值为:%d\n", p->data);
}
else
{
printf("不存在第i个的值");
}
}
void SLTFind2(SLTNode* phead, SLTDataType y) //查找y这个值的位置
{
SLTNode* pcur = phead;
int index = 0;
while (pcur)
{
if (pcur->data == y)
{
printf("下标值为%d\n", index);
return;
}
pcur = pcur->next;
index++;
}
printf("没找到\n");
}
void SListDesTroy(SLTNode** pphead) //销毁链表
{
assert(pphead && *pphead); //避免传入空的二级指针和空链表
SLTNode* pcur = *pphead;
while (pcur)
{
SLTNode* next = pcur->next;
free(pcur);
pcur = next;
}
*pphead = NULL; //避免成为野指针
}
int main()
{
//(1)
SLTNode* plist = NULL;
int n = 0;
printf("请输入单链表的指定长度:\n");
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
int x = 0;
scanf("%d", &x);
SLTPushFront(&plist, x);
}
PrintSLT(plist);
//(2)
printf("请输入要插入的下标i和元素x:\n");
int i = 0, x = 0;
scanf("%d%d", &i, &x);
SLTInsert(&plist, i, x);
PrintSLT(plist);
//(3)
printf("请输入要删除的下标i:\n");
scanf("%d", &i);
SLTErase(&plist, i);
PrintSLT(plist);
//(4)
printf("请输入要查找的位置i:\n");
scanf("%d", &i);
SLTFind1(plist, i);
//(5)
printf("请输入要查找的元素y:\n");
int y = 0;
scanf("%d", &y);
SLTFind2(plist, y);
//(6)销毁链表,归还申请空间
SListDesTroy(&plist);
printf("链表已销毁\n");
return 0;
}