题目:
输入一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
进阶:仅用一趟扫描实现。
链表节点定义如下:
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
C语言版本:
struct ListNode{
int val;
ListNode *next;
}
请提交如下形式的函数:
ListNode* removeNthFromEnd(ListNode* head, int n) {
}
大一学C时链表了解得并不是很多,趁此机会好好复习(预习)一下。
第一次运行代码时出现了bug,发现只要删除第二个节点即倒数第N-1个节点以及第一个节点都会出问题。重新审阅了一遍代码后发现第一个指针向前移动N-1个节点时就已经指向Null了,因此需要对这两种情况单独讨论。
#include <stdio.h>
#include <stdlib.h>
//线性表 链式结构
typedef struct listNote{
int val;
struct listNote *next;
}ListNode;
struct listNote*AppendNode(struct listNote*head);//增加节点
void DeleteMemory(struct listNote *head);//释放内存
void Disply(struct listNote *head);//显示节点信息
ListNode* removeNthFromEnd(ListNode* head, int n);//删除倒数第N个节点
int main()
{
int i = 0;
int n = 0;
struct listNote *head = NULL;
char c;
scanf("%c",&c);
while(c == 'y')
{
head = AppendNode(head);
Disply(head);
scanf(" %c",&c);
i++;
}
printf("是否删除节点?");
scanf(" %c",&c);
while(c == 'y')
{
printf("删除第几个节点");
scanf(" %d",&n);
head = removeNthFromEnd(head,n);
Disply(head);
printf("是否删除节点?");
scanf(" %c",&c);
}
DeleteMemory(head);
return 0;
}
struct listNote *AppendNode(struct listNote*head)
{
struct listNote *p = NULL,*pr = head;
int val;
p = (struct listNote*)malloc(sizeof(struct listNote));
if(p == NULL)
{
printf("No enough memory to allocate!\n");
exit(0);
}
if(head == NULL)
{
head = p;
}
else
{
while (pr->next!= NULL )
{
pr = pr->next;
}
pr->next = p;
}
printf("Input node data:");
scanf("%d",&val);
p->val = val;
p->next = NULL;
return head;
};
void DeleteMemory(struct listNote *head)
{
struct listNote *p = head,*pr = NULL;
while(p != NULL)
{
pr = p;
p = p->next;
free(pr);
}
}
void Disply(struct listNote *head)
{
struct listNote *p = head;
while(p != NULL)
{
printf("数据:%d\n",p->val);
p = p->next;
}
}
ListNode* removeNthFromEnd(ListNode* head, int n)
{
ListNode *pre = head, *last = head;//双重指针
ListNode *pr = NULL;
int i;
int j = 0;
for(i = 0;i < n+1;i++)
{
if (pre!=NULL)
{
pre = pre->next;
if(pre == NULL)
{
j++;
}
}
else //计数器
{
j++;
}
if(j == 2)
{
pr = head;
head = pr->next;
free(pr);
}
else if(j == 1 && i == n)
{
pr = head->next;
head->next = pr->next;
free(pr);
}
}
if(pre!=NULL)
{
while(pre!=NULL)
{
pre = pre->next;
last = last->next;
}
pr = last->next;
last->next = pr->next;
free(pr);
}
return head;
}