一:单链表的结构类型sList
sList单链表结构类型中包括:ListNode * first 、ListNode * last 、size_t size 三个成员变量分别是,指向头结点的指针,指向尾部节点的指针,以及链表的大小(即结点的个数)。
而ListNode 链表结点类型的成员包括 data域(数据域)、*next(指针域)指向下一个同样类型结点的指针域。
二、链表的结构体类型定义
三单链表中重要函数
1.购买结点_BuyNode()
函数返回一个指向ListNode类型的指针s,参数利用回调函数实现对数据域的初始化(ElemType x = ElemType()),
利用malloc函数申请一个结点让s指针指向,该节点,申请出来之后s不能指向空,然后初始化结点,data域为回调函数所给参数,*next指向空。
2.初始化链表init_slist
定义一个链表,要对其进行初始化,必须要先申请一个结点,也就是头结点,对其进行初始化,让链表的头指针,和尾指针同时指向s指针所指向的地方。 链表的size赋值为0表示链表结点为0个。
3.尾插push_back 、头插push_front
链表的尾插、头插是动态申请空间,申请一个指针s指向结点类型
尾插:首先申请一个s指针指向ListNode类型, 然后让list->last->next = s (让尾指针的next域,指向新结点),在让list->last= s(让链表的last指针直线s),最后记得给size++。
头插:首先申请一个s指针指向ListNode,,然后让list->front->next = s(让头指针的next域,指向新结点),再让s->next = list->front->next,最后记得size++。
4.头删pop_front、尾删pop_back
头删、尾删必须链表中有结点,判断条件list->size>=0.
头删:在链表不为空的情况下,先定义一个指向要删除的结点p (ListNode * p = list->front->next);其次list->front->next = p->next; 然后free(p);free(p)的同时就要让p = NULL;还要判断一下删除的结点是否是最后一个结点,如果是最后一个结点(判断条件p->size == 1),则需要list->last = list->front;最后一定要size--
尾删:在链表不为空的情况下,整体思想是先定义一个p指针指向头结点通过循环找得到链表最后一个结点的上一个结点(循环条件list->next != NULL),list->next不空的话,p = p->next;找到最后一个的上一个就可以free(list->last);然后p->last->next = NULL、list->last = p;最后别忘了size--;
5.显示函数show
定义一个指向list->front->next 的 p 指针,利用循环 p!= NULL, p = p->next,显示输出。
6.按值插入 insert_value
按值插入:前提是顺序是有序的,让p的next的data和value去比较,这样才更加容易定位要插入的位置。
首先buynode(), 定义一个p指向头结点 ,循环条件while(p->next != NULL && p->next->data < value)所要比较的不能为空,并且value大于data时 p= p->next,当跳出循环时候,不是p->next为空,就是p->next->date 不小于value, 当跳出循环时候,需要判断一下是哪一种情况if(p->next == NULL),那就需要先把list的last指针指向s,最后再把s连接到p指针的后面。
7.排序 sort
排序的思想是:把链表分成两部分,将后面部分的数据"摘下来",然后定位所要在屁股后面连接的p指针,一个一个与前面数据比较,找到自己位置按值插入即可。
排序:前提list->size == 0 || list->size == 1 直接return。首先把链表分开:ListNode * s = list->first->next , ListNode * q = s->next; list->last = s; s->next = NULL;将第二部分的数据插进去,循环条件(s != NULL);再把s = p ; p = p->next; 定义ListNode * p = list->front ;然后内部循环,找到p位置,然后循环条件是(p->next != NULL && p->next->data < s->data) p= p->next; 所要比较的不能为空,并且s->data大于p->next->data时 p= p->next,当跳出循环时候,不是p->next为空,就是p->next->date 不小于s->data, 当跳出循环时候,需要判断一下是哪一种情况if(p->next == NULL),那就需要先把list的last指针指向s,最后再把s连接到p指针的后面。
8.逆置函数reserve
逆置函数:和sort 一样首先把链表先分成两部分,然后再头插
9。 clean 和destroy
清除函数:list->size == 0 ,直接return,清除结点,要一个一个删除,每次删头后面的那个结点,定义一个指向list->front->next 的P 结点, 然后循环删除,循环条件(p != NULL) list->front->next = p->next; free(p) ; list->front->next = p;最后要让list->last = list->front;list->size = 0;
摧毁函数:先调用清理函数,然后free头结点,最后预防野指针