题目:
解题思路:
SListPop函数的设计需要尤其注意,首先需要画图画出三种情况来讨论一下边界问题。特别是头结点的情况,处理尾节点时循环边界的选择上,然后就是删除中间值的情况,并且在最后进行一个返回,这里的返回也同样需要注意,返回之前要提前存一下头结点,遍历的过程中指针位置会发生变化,如果不把头结点先存起来,返回会出问题
代码:
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
typedef struct SList
{
int data;
struct SList* next;
}SL;
void SListInit(SL** ps)
{
*ps = (SL*)malloc(sizeof(SL));
(*ps)->next = NULL;
}
void SListCreate(SL** ps, int n)
{
SL* cur = *ps;
int x = 0;
while (n)
{
scanf("%d", &x);
getchar();
SL* newnode = (SL*)malloc(sizeof(SL));
newnode->data = x;
cur->next = newnode;
cur = newnode;
n--;
}
cur->next = NULL;
}
SL* SListPop(SL** ps, int i, int n)
{
SL* cur = (*ps)->next;//用来迭代的节点
SL* prev = cur;//prev来记录cur的前一个节点的位置
SL* prevHead = prev;//保存一下prev的头结点便于用于返回
int j = 1;
if (i == 2)//头结点删除要单独讨论
{
*ps = cur->next;
free(cur);//每一步free掉过后要注意置空,防止内存泄露
cur = NULL;
return *ps;
}
else
{
while (n + 1)
//这里要使用n+1的原因是如果需要删除的是尾节点
//那么我们需要进去到if函数处理一下,把最后一个删除掉
{
if (j + 1 == i)
{
prev->next = cur->next;
free(cur);
cur = NULL;
return prevHead;//注意这里要返回prev的头指针
}
prev = cur;//prev每次记录一下cur的前一个位置
cur = cur->next;
j++;
n--;
}
}
}
int main()
{
SL* plist = NULL;
SListInit(&plist);
int n = 0;
scanf("%d", &n);
getchar();
SListCreate(&plist, n);
int i = 0;
scanf("%d", &i);
getchar();
//如果i的序号大于i节点的后一个节点或者小于等于1都打印error
if (i > n + 1 || i <= 1)
printf("error!");
else
{
SL* output = SListPop(&plist, i, n);
while (output)
{
printf("%d ", output->data);
output = output->next;
}
}
return 0;
}