C语言 单链表的相关操作(头插法,尾插法,插入,删除,释放,查找)
#include<stdio.h> #include<stdlib.h> #include<time.h> struct LinkList { int data; struct LinkList* next; }*head; void GreateLinkListHead(struct LinkList* head); //头插法建立链表 void GreatLinklistTail(struct LinkList* head); //尾插法 建立链表 int LinkListInsert(struct LinkList* head, int i); //插入节点 int LinkListnode_Find(struct LinkList* head); //查找节点并返回其值 int LinkListdate_Find(struct LinkList* head, int i); //i为查找的数据 int LinkListnode_Delete(struct LinkList* head); //i为要删除的节点 void LinkListDatePrint(struct LinkList* head); //链表的输出 void LinkListClean(struct LinkList* head); //链表的整表删除 /** *为了建立、使用、维护链表,对链表的操作如下: *建立链表 *遍历链表 *尾部追加 *删除结点 *查找结点 */ /******************************************************************************/ int main(void) { GreateLinkListHead(head); LinkListDatePrint(head); LinkListClean(head); return 0; } /******************************************************************************/ //链表数据的输出 /*思路: 1,开辟一个节点p 2,令节点p指向第一个节点 3,通过循环打印出每个节点的值 */ void LinkListDatePrint(struct LinkList* head) { struct LinkList* p; int j = 1; p = (struct LinkList*)malloc(sizeof(struct LinkList)); p = head->next; while (p) { printf("第%d个节点所存储的数据是:\n", j + 1); p = p->next; } free(p); printf("链表数据打印完成!\n"); } //链表的整表删除 /*思路: 1,声明节点p,q 2,将第一个节点赋给p,下一个赋给 q 3,循环执行释放p和将q赋给p操作 */ void LinkListClean(struct LinkList* head) { struct LinkList* p, * q; p = head->next; q = p->next; while (p) { free(p); p = q; q = q->next; } free(q); printf("链表整表释放完成!"); } //链表的建立 //头插法 /*思路: 1,声明节点p,以及头结点head,并使节点指向NULL 2,通过循环 开辟节点p,并且 存储数据 3,先后继后前驱算法 */ void GreateLinkListHead(struct LinkList* head) { struct LinkList* p; int i, j; srand((unsigned int)time(NULL)); head = (struct LinkList*)malloc(sizeof(struct LinkList)); //为头结点分配内存 head->next = NULL; //将头结点的指针域指向0 printf("请输入所需开辟的节点个数:"); scanf_s("%d", &i); fflush(stdin); for (j = 0; j < i; j++) { p = (struct LinkList*)malloc(sizeof(struct LinkList)); printf("请输入第%d个节点存储的数据:", j + 1); scanf_s("%d", &p->data); // p->data = rand() % 100 + 1; p->next = (head)->next; //关键语句!!!! 头插法核心 head->next = p; } printf("链表建立完成!"); } //尾插法 /*思路: 1,声明 节点结构体指针,尾指针 2,开辟头指针 将头指针指向空 3,循环赋值 4, 核心算法 5,将头指针指向空 */ void GreatLinklistTail(struct LinkList* head) { struct LinkList* p, * r; //声明 节点结构体指针,尾指针 int i, j; //计数器 head = (struct LinkList*)malloc(sizeof(struct LinkList));//开辟头指针 head->next = NULL; //先将头指针指向空 r = head; printf("请输入所需开辟节点的个数: "); scanf_s("%d", &i); fflush(stdin); for (j = 0; j < i; j++) { p = (struct LinkList*)malloc(sizeof(struct LinkList)); //开辟节点内存 printf("请输入第%d个节点所存储的数据:", j + 1); scanf_s("%d", &p->data); r->next = p; //尾插菊花法 最核心算法 r = p; } r->next = NULL; printf("链表建立完成!"); } //节点的插入 int LinkListInsert(struct LinkList* head, int i) { struct LinkList* p; //声明一个节点,指向头结点 struct LinkList* s; //声明插入的那个节点 int j = 1; //初始化计数器j = 1, 因为链表从1开始计数 p = head; //让p节点指向 头结点 while (j < i && p) //当 j<i 的时候遍历链表 { p = p->next; j++; } if (j > i || !p) //如果一直找到表尾都没找到,则第i个元素不存在 { return 0; //则终止函数的运行 } //否则就找到了要插入的那个节点 s = (struct LinkList*)malloc(sizeof(struct LinkList)); //开辟一个新节点 printf("请输入要插入的值"); scanf_s("%d", &s->data); //先后继再前驱 s->next = p->next; p->next = s; return 1; } //节点的查找并返回其值 //假设数据的类型是 int int LinkListnode_Find(struct LinkList* head) //查找第i个元素 { struct LinkList* p; // 声明一个节点指向 第一个节点 int i; //声明要查找的位置变量i int j; //声明一个计数器 j=1; int *e; p = head->next; printf("请输入要查找的节点"); scanf_s("%d", &i); //输入要查找的数据 fflush(stdin); while (p && j < i) //遍历循环寻找 第i个元素 { p = p->next; j++; } if (!p || j > i) { return 0; } *e = p->data; return *e; } //单链表中数据的查找 int LinkListdate_Find(struct LinkList* head, int i) //i为查找的数据 { struct LinkList* p; // 声明一个节点指向 第一个节点 int j = 1; //声明一个计数器 j=1; p = head->next; while (p->data != i) //遍历循环寻找 第i个元素 { p = p->next; j++; } if (!p || j > i) { return 0; } else { return j; } } //单链表删除操作 int LinkListnode_Delete(struct LinkList* head) //i为要删除的节点 { struct LinkList* p; //声明节点p指向链表的第一个节点 struct LinkList* q; int i;//要删除的节点 int j = 1; //声明一个计数器 和一个容器 p = head->next; //p节点指向第一个节点 printf("请输入要删除的节点标号:"); scanf_s("%d", &i); fflush(stdin); while (j < i && p) { p = p->next; j++; } if (!p || j > i) { return 0; } q = p->next; //关键语句 p->next = q->next; // p->next = p->next->next; //关键语句也可以这么写 free(q); return 1; }