单链表是数据结构中十分常见,许多互联网公司笔试面试题好多都是单链表延伸出的,因此实能现一个单链表的基本操作很有必要,而且能让它不出现Bug还需要更细心。
基本功能:
1.添加元素 2.头插元素
3.尾插元素 4.头删元素
5.尾删元素 6.销毁链表
7.删除指定元素 8.指定位置插入元素
代码如下:
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<Windows.h> #include<assert.h> typedef int DataType; typedef struct Slist { struct Slist *next; DataType data; }Slist; Slist List; Slist *BuySlist(DataType x) //添加元素 { Slist *node = (Slist *)malloc(sizeof(Slist)); assert(node); node->data = x; node->next = NULL; return node; } void ListPushback(Slist **head, DataType x) //尾插元素 { if (*head == NULL) //没有元素的情况 { *head = BuySlist(x); } else { Slist *cur = *head; while (cur->next != NULL) { cur = cur->next; } cur->next = BuySlist(x); } } void ListPopBack(Slist **head) //尾删元素 { if (*head == NULL) //没有元素 { return; } else if ((*head)->next == NULL) //只有一个元素 { free(*head); *head = NULL; //防止内存泄漏 } Slist *cur = *head; Slist *pos = cur; while (cur->next != NULL) { pos = cur; //上下位置不能变 cur = cur->next; } free(cur); cur = NULL; pos->next = NULL; //此时pos为尾结点 } void ListPushFront(Slist **head, DataType x) //头插元素 { if (*head == NULL) //没有结点 { *head = BuySlist(x); return; } Slist *new; new = BuySlist(x); new->next = *head; *head = new; } void ListPopFront(Slist **head)//头删元素 { if (*head==NULL) { return; } //else if ((*head)->next == NULL)//一个节点 //注意这里不能写成*head->next,这是错的,存在优先级问题 //{ // free(*head); // *head = NULL; //} Slist *cur = (*head)->next; free(*head); *head = cur; } void ListDestory(Slist **head) //销毁单链表 { Slist *cur = *head; while (cur) { Slist *next = cur->next; free(cur); cur = next; } *head = NULL; } Slist *Find(Slist *head, DataType x) //查找指定元素,返回下标 { Slist *cur = head; while (cur!=NULL) { if (cur->data == x) { return cur; } cur = cur->next; } return NULL; } void ListErase(Slist **head, Slist *pos) //删除任意节点 { assert(pos&&*head); if ((*head) == pos) //删除头节点 { ListPopFront(head); } else if (pos->next == NULL) //删除尾节点 { ListPopBack(head); } else { Slist *prev = *head; while (prev->next != pos) { prev = prev->next; } prev = pos->next; free(pos); } } void Insert(Slist **head, Slist *pos, DataType x) //插入元素 { assert(*head&&pos); Slist *cur = *head; Slist *tmp=NULL; while (cur->next!=pos) { cur=cur->next; } /*tmp->data = x; tmp->next = pos;*/ tmp = BuySlist(x); tmp->next = pos; cur->next = tmp; } void print(Slist *head) //打印元素 { Slist *cur = head; while (cur != NULL) { printf("%d->", cur->data); cur = cur->next; } printf("NULL"); printf("\n"); } void test1(Slist *list) { list = NULL; ListPushback(&list, 1); //不能传list,实际上传的是地址的值,要传二级指针 ListPushback(&list, 7); ListPushback(&list, 4); ListPushback(&list, 15); ListPushFront(&list, 10); Slist *pos = Find(list, 7); Insert(&list, pos, 2); //ListPopFront(&list); //ListPopBack(&list); print(list); } int main() { test1(&List); system("pause"); return 0; }
test函数根据自己的使用情况来调用任意函数