链表是一种常见的基础数据结构,结构体指针在这里得到了充分的利用。链表可以动态的进行存储分配,也就是说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节点。
链表都有一个头指针,一般以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 <stdio.h>
#include <stdlib.h>
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("%d\t", 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语言