单链表是方向单一的链表,即就是只能从前向后访问,不能从后向前访问。这篇文章,我
将整理出单链表的一些基本功能。
1.尾插 2.尾删 3.头插 4.头删5.打印 6.插入7.删除指定元素 8.删除指定元素的全部9.删除指
定位置的元素10.排序(此文先给出基本的冒泡排序,其他排序算法之后再给出)
下边,我就这些功能一个一个进行说明,尽量配图~~(这里的单链表不带头结点)
为了方便大家读以下的代码,我给出结构体的定义。
- typedef struct LinkNode
- {
- DataType data;
- struct LinkNode *next;
- }LinkNode,*pLinkNode;
- typedef struct LinkList
- {
- LinkNode *pHead;
- }LinkList,*pLinkList;
1.尾插:先要找到链表的尾部,然后进行插入。
具体实现代码如下:
- void PushBackLinkList(pLinkList pList, DataType x)
- {
- assert(pList);
- pLinkNode add = CreatNode(x);
- pLinkNode tmp = pList->pHead;
- if (NULL == pList->pHead)//linklist is empty
- {
- pList->pHead = add;
- add->next = NULL;
- return;
- }
- while (tmp->next)//linklist is not empty
- {
- tmp = tmp->next;
- }
- tmp->next = add;
- add->next = NULL;
- printf("successful push back\n");
- }
2.尾删:顾名思义,找到链表的结尾,将其删除。看图:
下边给出代码实现:
- void PopBackLinkList(pLinkList pList)
- {
- assert(pList);
- if (NULL == pList->pHead)
- {
- printf("linklist is empty.\n");
- return;
- }
- pLinkNode cur = pList->pHead;
- pLinkNode prev = pList->pHead;
- if (NULL == cur->next->next)//linklist only has an element.
- {
- free(cur->next);
- cur->next = NULL;
- }
- else
- {
- while (cur->next)
- {
- prev = cur;
- cur = cur->next;
- }
- free(prev ->next);
- prev->next = NULL;
- }
- printf("successful popback");
- }
3.头插:
如果链表是空链表,直接插入就可;有一个元素和有多个元素一样处理。下边图解:
下边给出代码实现:
- void PushFrontLinkList(pLinkList pList, DataType x)
- {
- assert(pList);
- pLinkNode add = CreatNode(x);
- pLinkNode tmp = pList->pHead;
- if (NULL == pList->pHead)//linklist is empty
- {
- pList->pHead = add;
- add->next = NULL;
- return;
- }
- add->next = tmp;
- pList->pHead = add;
- printf("successful pushfront.\n");
- }
4.头删:
如果链表是空,不删除;如果是一个结点,删除后将头指针置为NULL;如果是多个结
点,调整指针就好。图解:
下边给出代码实现:
- void PopFrontLinkList(pLinkList pList)
- {
- assert(pList);
- if (NULL == pList->pHead)
- {
- printf("linklist is empty.\n");
- return;
- }
- pLinkNode tmp = pList->pHead;
- pLinkNode del = pList->pHead;
- if (NULL == tmp->next->next)
- {
- free(tmp->next);
- pList->pHead = NULL;
- }
- else
- {
- del = tmp->next;
- tmp = tmp->next->next;
- free(del);
- }
- printf("successful popfront.\n");
- }
5.打印:这个比较简单。
6.指定位置之前插入指定元素:这个我们需要有个find函数来查找指定位置的指针
我们约定:如果是空链表,直接将元素插在链表中。
下边给出代码:
- void InsertLinkList(pLinkList pList, DataType x, pLinkNode pos)//insert the front of pos
- {
- assert(pList);
- pLinkNode p = CreatNode(x);
- pLinkNode tmp = pList->pHead;
- if (NULL == pList->pHead)//check:if linklist is empty,we insert the element in the linklist.
- {
- tmp->next = p;
- p->next = NULL;
- return;
- }
- if (pos == pList->pHead->next)
- {
- PushFrontLinkList(pList, x);
- return;
- }
- while (tmp->next != pos)
- {
- tmp = tmp->next;
- }
- p->next = tmp->next;
- tmp->next = p;
- printf("successful insertion.\n");
- }
7.删除指定元素:
如果链表是空,直接返回;如果链表只有一个元素,如果第一个元素就是指定元素,删
除,然后返回;如果多个元素,找到元素直接删除。
代码:
- void Remove(pLinkList pList, DataType x)
- {
- assert(pList);
- pLinkNode cur = pList->pHead;
- pLinkNode del = pList->pHead;
- pLinkNode prev = pList->pHead;
- if (NULL == pList->pHead)
- {
- printf("linklist is empty.\n");
- return;
- }
- if (cur->next == NULL)//只有一个元素
- {
- if (cur->data == x)
- {
- free(cur->next);
- pList->pHead = NULL;
- return;
- }
- }
- else
- {
- while (cur != NULL)
- {
- if (cur->data == x)
- {
- del = cur;
- pList->pHead = cur->next;
- free(del);
- return;
- }
- cur = cur->next;
- while (cur != NULL)
- {
- if (cur->data == x)
- {
- prev->next = cur->next;
- free(cur);
- return;
- }
- prev = cur;
- cur = cur->next;
- }
- }
- }
- printf("successful remove.\n");
- }
8.删除指定元素的全部:
给定元素x,删除链表中所有data为x的元素。如果是空链表,直接返回。先判断链表的
第一个元素。
给出代码:
- void RemoveAll(pLinkList pList, DataType x)
- {
- assert(pList);
- if (NULL == pList->pHead)
- {
- printf("linklist is empty.\n");
- return;
- }
- pLinkNode cur = pList->pHead;
- pLinkNode prev = pList->pHead;
- while (cur != NULL) //判断第一个结点
- {
- if (cur->next == NULL) //linklist has one element.
- {
- if (cur->data == x)
- {
- free(cur->next);
- pList->pHead = NULL;
- return;
- }
- }
- else if (pList->pHead->data == x) //如果不是一个结点,且第一个结点的数据是x
- {
- pList->pHead = cur->next;
- free(cur);
- cur = pList->pHead;
- }
- else
- break;
- }
- cur = cur->next;
- prev = pList->pHead;
- while (cur)
- {
- if (cur->data == x)
- {
- prev->next = cur->next;
- free(cur);
- cur = prev;
- }
- prev = cur;
- cur = cur->next;
- }
- printf("successful removeall.\n");
- }
9.删除指定位置的元素:
如果链表是空,直接返回;如果只有一个元素,如果这个元素就是pos位置,删除,返
回;如果多个元素,同样先判断第一个位置,如果是,直接删除,返回,如果不是,继
续向后找。
代码:
- void Erase(pLinkList pList, pLinkNode pos)
- {
- assert(pList);
- if (NULL == pList->pHead)
- {
- printf("linklist is empty.\n");
- return;
- }
- pLinkNode cur = pList->pHead;
- pLinkNode del = pList->pHead;
- pLinkNode prev = pList->pHead;
- if (cur->next == NULL)//如果只有一个元素
- {
- if (pos == cur)
- { //第一个结点就是pos位置
- free(pList->pHead);
- pList->pHead = NULL;
- }
- return;
- }
- if (pos == cur)
- { //第一个结点就是pos位置
- del = cur;
- pList->pHead = cur->next;
- free(del);
- return;
- }
- cur = cur->next;
- while(cur)
- {
- if(cur == pos)
- {
- prev->next = cur->next;
- free(cur);
- return;
- }
- prev = cur;
- cur = cur->next;
- }
- }
10.冒泡排序:
给出代码:
- void BottleSort(pLinkList pList)
- {
- assert(pList);
- if (NULL == pList->pHead || NULL == pList -> pHead->next )
- {
- printf("linklist is empty or linklist has one element.\n");
- return;
- }
- pLinkNode front = pList->pHead;
- pLinkNode tail = NULL;
- while (front != tail)
- {
- while (front->next != tail)
- {
- if (front->data > front->next->data)
- {
- DataType tmp = front->data;
- front->data = front->next->data;
- front->next->data = tmp;
- }
- front = front->next;
- }
- tail = front;
- front = pList->pHead;
- }
- }
为了方便读者理解,下边给出程序源码:
- //LinkList.h
- #ifndef __LINKLIST_H__
- #define __LINKLIST_H__
- #define _CRT_SECURE_NO_WARNINGS 1
- #include<stdio.h>
- #include <assert.h>
- #include<stdlib.h>
- typedef int DataType;
- enum OP
- {
- EXIT,
- PUSHBACK,
- POPBACK,
- PUSHFRONT,
- POPFRONT,
- PRINT,
- INSERT,
- REMOVE,
- REMOVEALL,
- ERASE,
- SORT
- };
- typedef struct LinkNode
- {
- DataType data;
- struct LinkNode *next;
- }LinkNode,*pLinkNode;
- typedef struct LinkList
- {
- LinkNode *pHead;
- }LinkList,*pLinkList;
- void InitLinkList(pLinkList pList);
- void DestroyLinkList(pLinkList pList);
- void PushBackLinkList(pLinkList pList,DataType x);
- void PopBackLinkList(pLinkList pList);
- void PushFrontLinkList(pLinkList pList, DataType x);
- void PopFrontLinkList(pLinkList pList);
- void PrintLinkList(pLinkList pList);
- void InsertLinkList(pLinkList pList, DataType x, pLinkNode pos);
- void Remove(pLinkList pList, DataType x);
- void RemoveAll(pLinkList pList, DataType x);
- void Erase(pLinkList pList, pLinkNode pos);
- void BottleSort(pLinkList pList);
- void menu();
- #endif//__LINKLIST_H__
- //LinkList.c
- #include"LinkList.h"
- pLinkNode CreatNode(DataType x)
- {
- pLinkNode p = (pLinkNode)malloc(sizeof(LinkNode));
- if (NULL == p)
- {
- printf("out of memory.\n");
- exit(EXIT_FAILURE);
- }
- p->data = x;
- return p;
- }
- pLinkNode find(pLinkList pList,DataType x)
- {
- assert(pList);
- pLinkNode tmp = pList->pHead;
- if (pList->pHead == NULL)
- {
- printf("pList is empty.\n");
- }
- while (tmp->data != x)
- {
- tmp = tmp->next;
- }
- return tmp;
- }
- void InitLinkList(pLinkList pList)
- {
- assert(pList);
- pList ->pHead = NULL;
- }
- void DestroyLinkList(pLinkList pList)
- {
- assert(pList);
- pLinkNode p = pList->pHead;
- pLinkNode del = NULL;
- if (NULL == pList->pHead)
- {
- printf("linklist is empty.\n");
- return;
- }
- while (p)
- {
- pList->pHead = p->next;
- free(p);
- p = pList->pHead;
- }
- pList->pHead = NULL;
- }
- void PushBackLinkList(pLinkList pList, DataType x)
- {
- assert(pList);
- pLinkNode add = CreatNode(x);
- pLinkNode tmp = pList->pHead;
- if (NULL == pList->pHead)//linklist is empty
- {
- pList->pHead = add;
- add->next = NULL;
- return;
- }
- while (tmp->next)//linklist is not empty
- {
- tmp = tmp->next;
- }
- tmp->next = add;
- add->next = NULL;
- printf("successful push back\n");
- }
- void PopBackLinkList(pLinkList pList)
- {
- assert(pList);
- if (NULL == pList->pHead)
- {
- printf("linklist is empty.\n");
- return;
- }
- pLinkNode cur = pList->pHead;
- pLinkNode prev = pList->pHead;
- if (NULL == cur->next->next)//linklist only has an element.
- {
- free(cur->next);
- cur->next = NULL;
- }
- else
- {
- while (cur->next)
- {
- prev = cur;
- cur = cur->next;
- }
- free(prev ->next);
- prev->next = NULL;
- }
- printf("successful popback");
- }
- void PushFrontLinkList(pLinkList pList, DataType x)
- {
- assert(pList);
- pLinkNode add = CreatNode(x);
- pLinkNode tmp = pList->pHead;
- if (NULL == pList->pHead)//linklist is empty
- {
- pList->pHead = add;
- add->next = NULL;
- return;
- }
- add->next = tmp;
- pList->pHead = add;
- printf("successful pushfront.\n");
- }
- void PopFrontLinkList(pLinkList pList)
- {
- assert(pList);
- if (NULL == pList->pHead)
- {
- printf("linklist is empty.\n");
- return;
- }
- pLinkNode tmp = pList->pHead;
- pLinkNode del = pList->pHead;
- if (NULL == tmp->next->next)
- {
- free(tmp->next);
- pList->pHead = NULL;
- }
- else
- {
- del = tmp->next;
- tmp = tmp->next->next;
- free(del);
- }
- printf("successful popfront.\n");
- }
- void PrintLinkList(pLinkList pList)
- {
- assert(pList);
- if (NULL == pList->pHead)
- {
- printf("linklist is empty.\n");
- return;
- }
- pLinkNode tmp = pList->pHead;
- while (tmp)
- {
- printf("%d->",tmp->data);
- tmp = tmp->next;
- }
- printf("over\n");
- }
- void InsertLinkList(pLinkList pList, DataType x, pLinkNode pos)//insert the front of pos
- {
- assert(pList);
- pLinkNode p = CreatNode(x);
- pLinkNode tmp = pList->pHead;
- if (NULL == pList->pHead)//check:if linklist is empty,we insert the element in the linklist.
- {
- tmp->next = p;
- p->next = NULL;
- return;
- }
- if (pos == pList->pHead->next)
- {
- PushFrontLinkList(pList, x);
- return;
- }
- while (tmp->next != pos)
- {
- tmp = tmp->next;
- }
- p->next = tmp->next;
- tmp->next = p;
- printf("successful insertion.\n");
- }
- void Remove(pLinkList pList, DataType x)
- {
- assert(pList);
- pLinkNode cur = pList->pHead;
- pLinkNode del = pList->pHead;
- pLinkNode prev = pList->pHead;
- if (NULL == pList->pHead)
- {
- printf("linklist is empty.\n");
- return;
- }
- if (cur->next == NULL)//只有一个元素
- {
- if (cur->data == x)
- {
- free(cur->next);
- pList->pHead = NULL;
- return;
- }
- }
- else
- {
- while (cur != NULL)
- {
- if (cur->data == x)
- {
- del = cur;
- pList->pHead = cur->next;
- free(del);
- return;
- }
- cur = cur->next;
- while (cur != NULL)
- {
- if (cur->data == x)
- {
- prev->next = cur->next;
- free(cur);
- return;
- }
- prev = cur;
- cur = cur->next;
- }
- }
- }
- printf("successful remove.\n");
- }
- void RemoveAll(pLinkList pList, DataType x)
- {
- assert(pList);
- if (NULL == pList->pHead)
- {
- printf("linklist is empty.\n");
- return;
- }
- pLinkNode cur = pList->pHead;
- pLinkNode prev = pList->pHead;
- while (cur != NULL) //判断第一个结点
- {
- if (cur->next == NULL) //linklist has one element.
- {
- if (cur->data == x)
- {
- free(cur->next);
- pList->pHead = NULL;
- return;
- }
- }
- else if (pList->pHead->data == x) //如果不是一个结点,且第一个结点的数据是x
- {
- pList->pHead = cur->next;
- free(cur);
- cur = pList->pHead;
- }
- else
- break;
- }
- cur = cur->next;
- prev = pList->pHead;
- while (cur)
- {
- if (cur->data == x)
- {
- prev->next = cur->next;
- free(cur);
- cur = prev;
- }
- prev = cur;
- cur = cur->next;
- }
- printf("successful removeall.\n");
- }
- void Erase(pLinkList pList, pLinkNode pos)
- {
- assert(pList);
- if (NULL == pList->pHead)
- {
- printf("linklist is empty.\n");
- return;
- }
- pLinkNode cur = pList->pHead;
- pLinkNode del = pList->pHead;
- pLinkNode prev = pList->pHead;
- if (cur->next == NULL)//如果只有一个元素
- {
- if (pos == cur)
- { //第一个结点就是pos位置
- free(pList->pHead);
- pList->pHead = NULL;
- }
- return;
- }
- if (pos == cur)
- { //第一个结点就是pos位置
- del = cur;
- pList->pHead = cur->next;
- free(del);
- return;
- }
- cur = cur->next;
- while(cur)
- {
- if(cur == pos)
- {
- prev->next = cur->next;
- free(cur);
- return;
- }
- prev = cur;
- cur = cur->next;
- }
- }
- void BottleSort(pLinkList pList)
- {
- assert(pList);
- if (NULL == pList->pHead || NULL == pList -> pHead->next )
- {
- printf("linklist is empty or linklist has one element.\n");
- return;
- }
- pLinkNode front = pList->pHead;
- pLinkNode tail = NULL;
- while (front != tail)
- {
- while (front->next != tail)
- {
- if (front->data > front->next->data)
- {
- DataType tmp = front->data;
- front->data = front->next->data;
- front->next->data = tmp;
- }
- front = front->next;
- }
- tail = front;
- front = pList->pHead;
- }
- }
- void menu()
- {
- printf("*********1.尾插***************\n");
- printf("*********2.尾删***************\n");
- printf("*********3.头插***************\n");
- printf("*********4.头删***************\n");
- printf("*********5.打印***************\n");
- printf("*********6.插入***************\n");
- printf("*********7.删除指定元素********\n");
- printf("*********8.删除指定的全部*******\n");
- printf("*********9.删除指定位置的元素***\n");
- printf("*********10.排序****************\n");
- printf("*********0.退出*******\n");
- }
- //test.c
- #include"LinkList.h"
- void test()
- {
- LinkList list;
- pLinkNode pos = NULL;
- InitLinkList(&list);
- int input = 1;
- DataType x = 0;
- DataType y = 0;
- while (input)
- {
- menu();
- printf("please your choice:>");
- scanf("%d",&input);
- switch (input)
- {
- case EXIT:
- DestroyLinkList(&list);
- break;
- case PUSHBACK:
- printf("please input a number of insertion:>");
- scanf("%d",&x);
- PushBackLinkList(&list, x);
- break;
- case POPBACK:
- PopBackLinkList(&list);
- break;
- case PUSHFRONT:
- printf("please input a number of insertion:>");
- scanf("%d", &x);
- PushFrontLinkList(&list, x);
- break;
- case POPFRONT:
- PopFrontLinkList(&list);
- break;
- case PRINT:
- PrintLinkList(&list);
- break;
- case REMOVE:
- printf("please input a number of delete:>");
- scanf("%d", &x);
- Remove(&list, x);
- break;
- case REMOVEALL:
- printf("please input a number of delete:>");
- scanf("%d", &x);
- RemoveAll(&list, x);
- break;
- case ERASE:
- printf("please input a number of delete:>");
- scanf("%d", &x);
- pos = find(&list,x);
- Erase(&list, pos);
- break;
- case SORT:
- BottleSort(&list);
- break;
- case INSERT:
- printf("please input a number of insertion:>");
- scanf("%d", &x);
- printf("please input a number of the data of pos:>");
- scanf("%d", &y);
- pos = find(&list, y);
- InsertLinkList(&list, x, pos);
- break;
- }
- }
- }
- int main()
- {
- test();
- system("pause");
- return 0;
- }