链表是一种常见的基础数据结构,结构体指针在这里得到了充分的利用。链表可以动态的进行存储分配,也就是说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节点。
链表都有一个头指针,一般以head来表示,存放的是一个地址。链表中的节点分为两类,头结点和一般节点,头结点是没有数据域的。链表中每个节点都分为两部分,一个数据域,一个是指针域。
说到这里你应该就明白了,链表就如同车链子一样,head指向第一个元素:第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束。
创建链表:
typedef struct Node
{
int data;
struct Node *next;
} Node;
//创建链表
void createLink(Node *head, int size)
{
Node *rear = head;
int i;
for (i = 0; i < size; ++i)
{
Node *newnode = (Node *)malloc(sizeof(Node));
newnode->next = NULL;
scanf("%d", &newnode->data);
rear->next = newnode;
rear = newnode;
}
}
int mian()
{
Node *head = (Node *)malloc(sizeof(Node));
head->next = NULL;
createLink(head, 10); //创建链表
}
删除链表节点:
void delet(Node *head, int n)
{
Node *in;
int i = 0;
while (i < n && head != NULL)
{
in = head;
head = head->next;
i++;
}
if (head != NULL)
{
in->next = head->next;
free(head);
}
else
{
puts("节点不存在");
}
}
插入链表节点:
void insertLink(Node *head, int n)
{
int i = 0;
while (i < n && head != NULL)
{
head = head->next;
i++;
}
if (head != NULL)
{
Node *newnode = (Node *)malloc(sizeof(Node));
printf("输入要插入的值:");
scanf("%d", &newnode->data);
newnode->next = head->next;
head->next = newnode;
}
else
{
printf("节点不存在");
}
}
示例代码:
//链表创建、头插、尾插、删除、翻转、删除相同元素、遍历、判断链表是否为空 #include#include typedef struct Node { int data; struct Node *next; } Node; //创建链表 void createLink(Node *head, int size) { Node *rear = head; int i; for (i = 0; i < size; ++i) { Node *newnode = (Node *)malloc(sizeof(Node)); newnode->next = NULL; scanf("%d", &newnode->data); rear->next = newnode; rear = newnode; } } //遍历链表 void travelLink(Node *head) { Node *p = head->next; while (p != NULL) { printf("%dt", p->data); p = p->next; } putchar('n'); } //头插法 void insertForward(Node *head, int data) { Node *newnode = (Node *)malloc(sizeof(Node)); newnode->next = NULL; newnode->data = data; newnode->next = head->next; head->next = newnode; } //尾插法 void insertBack(Node *head, int data) { Node *newnode = (Node *)malloc(sizeof(Node)); newnode->next = NULL; newnode->data = data; Node *p = head; while (p->next != NULL) { p = p->next; } p->next = newnode; p = newnode; } //在第N个元素后插入元素 void insertLink(Node *head, int n) { int i = 0; while (i < n && head != NULL) { head = head->next; i++; } if (head != NULL) { Node *newnode = (Node *)malloc(sizeof(Node)); printf("输入要插入的值:"); scanf("%d", &newnode->data); newnode->next = head->next; //填充newnode节点的指针域,也就是说把in的指针域指向newnode的下一个节点 head->next = newnode; //填充t节点的指针域,把t的指针域重新指向in } else { printf("节点不存在"); } } //删除相同元素 void deleteSame(Node *head) { Node *curr = head->next; while (curr != NULL) { Node *pre = curr; Node *p = curr->next; while (p != NULL) { //若有相同的元素,则删除;否则两个指针继续向下走 if (curr->data == p->data) { pre->next = p->next; free(p); p = pre->next; } else { pre = pre->next; p = p->next; } } curr = curr->next; } } //删除第N个元素 void delet(Node *head, int n) { Node *in; int i = 0; while (i < n && head != NULL) { in = head; head = head->next; i++; } if (head != NULL) { in->next = head->next; free(head); } else { puts("节点不存在"); } } //翻转链表 void reverseLink(Node *head) { Node *curr; Node *pre = NULL; while (head->next != NULL) { curr = head->next; head->next = curr->next; curr->next = pre; pre = curr; } head->next = pre; } //删除链表 void deleteLink(Node *head) { Node *curr; while (head->next != NULL) { curr = head->next; head->next = curr->next; free(curr); } } //判断链表是否为空 void isEmpty(Node *head) { if (head->next == NULL) { printf("链表为空!n"); } else { printf("链表不为空!n"); } } int main() { //主函数中不能指定一个头指针,应该定义一个头指针指向头结点 Node *head = (Node *)malloc(sizeof(Node)); head->next = NULL; printf("输入元素:n"); createLink(head, 10); //创建链表 printf("遍历链表:"); travelLink(head); //遍历链表 printf("头插法:"); insertForward(head, 100); //头插法 travelLink(head); //遍历链表 printf("尾插法:"); insertBack(head, 200); //尾插法 travelLink(head); //遍历链表 printf("删除相同元素:"); deleteSame(head); //删除相同元素 travelLink(head); //遍历链表 printf("删除第5个元素:"); delet(head, 5); travelLink(head); //遍历链表 printf("在第3个元素后插入元素,"); insertLink(head, 3); //插入元素 travelLink(head); //遍历链表 printf("翻转链表元素:"); reverseLink(head); //翻转链表元素 travelLink(head); //遍历链表 printf("删除链表:"); deleteLink(head); //删除链表 isEmpty(head); //判断链表是否为空 return 0; }
测试结果:
参考文章:c语言链表详解(超详细)_Mr.Gzj的博客-CSDN博客_链表c语言



