链表中头结点会让插入与删除简化,但至于如何简化,为什么会简化可能不清楚,那我们就来实现一下删除与插入无头结点的代码。
无头结点实现插入,删除,遍历输出
#include"stdio.h"
#include"stdlib.h"
typedef struct Node {
int data;
struct Node* Next;
}*PNode;
int NoHead_ListInsert(PNode* List, int i, int e) {
PNode P = *List; int j = 1;
if (i == 1) { //无头结点时要对插入第一个结点单独操作
PNode l = (PNode)malloc(sizeof(struct Node));
l->data = e;
l->Next = P;
*List = l; //List = &l;
}
else {
while (P && j < i - 1) {
P = P->Next;
j++;
}
if (!P || i - 1 < j) {
printf("Input i error\n");
return 0;
}
PNode l = (PNode)malloc(sizeof(struct Node));
l->data = e;
l->Next = P->Next;
P->Next = l;
}
return 1;
}
int NoHead_Delete(PNode* List, int i) {
PNode P = *List; int j = 1;
if (!*List) { //无头结点,要单独判断这个链表是否为空
printf("empty\n");
return 0;
}
if (i == 1) { //无头结点,要对删除首结点单独操作
*List = P->Next;
free(P);
}
else {
while ((P->Next) && j < i - 1) { //P->Next 是咱们要删除的结点 必须保证这个删除结点存在
P = P->Next;
j++;
}
if (i - 1 < j || !(P->Next)) {
printf("input i error\n");
return 0;
}
PNode l = P->Next;
P->Next = l->Next;
free(l);
}
}
void NoHead_Print(PNode List) {
while (List) {
printf("%d ", List->data);
List = List->Next;
}
printf("\n");
}
int main() {
int In, De, in;
PNode List = NULL;
NoHead_ListInsert(&List, 0, 9);
scanf("%d", &In);
for (int i = 0; i < In; i++) {
scanf("%d",&in);
NoHead_ListInsert(&List, i + 1, in);
}
NoHead_Print(List);
scanf("%d", &De);
NoHead_Delete(&List, De);
NoHead_Print(List);
return 0;
}
对带头结点的链表实现
#include"stdio.h"
#include"stdlib.h"
typedef struct Node {
int data;
struct Node* Next;
}*PNode;
int ListInsert(PNode* List, int i, int e) {
PNode P = *List; int j = 0; //如果要插入第一个结点前,P要指向头结点,所以初始化P指向头结点
while (P && j < i - 1) { //有头结点可以统一操作
P = P->Next;
j++;
}
if (!P || i - 1 < j) {
printf("Input i error\n");
return 0;
}
PNode l = (PNode)malloc(sizeof(struct Node));
l->data = e;
l->Next = P->Next;
P->Next = l;
return 1;
}
int Delete(PNode* List, int i) {
if (!(*List)->Next) {
printf("List Empty\n");
return 0;
}
PNode P = *List; int j = 0; //删除第一个结点时,P指向头结点
while (P->Next && j < i - 1) { //P->Next 为要删除结点,必须保证存在
P = P->Next;
j++;
}
if (!(P->Next) || i - 1 < j) {
printf("input i error\n");
return 0;
}
PNode l = P->Next;
P->Next = l->Next;
free(l);
return 1;
}
void Print(PNode List) {
List = List->Next; //有头结点,要指向第一个有效结点
while (List) {
printf("%d ", List->data);
List = List->Next;
}
printf("\n");
}
int main() {
int In, De, in;
PNode List = (PNode)malloc(sizeof(struct Node));
List->Next = NULL; //注意初始化时要让最后一个结点为NULL
ListInsert(&List, 0, 1);
scanf("%d", &In);
for (int i = 0; i < In; i++) {
scanf("%d", &in);
ListInsert(&List, i + 1, in);
}
Print(List);
scanf("%d", &De);
Delete(&List, De);
Print(List);
}
实现代码的时候要注意:
- 插入和删除的第i个结点时,要找到第i-1个结点,在找结点时,注意这两个操作的while循环条件不同,
因为插入不需要管第i个结点是否为空,但删除必须要第i个结点不为空