#include<stdio.h>
#include<stdlib.h>
#include <assert.h>
#define ElemType int
typedef struct Node//定义节点
{
ElemType data;//存放内容
struct Node* next;//存储下一个节点的地址,Node类型的next指针
}Node, *PNode;//定义了节点的类型Node和指针类型pNode
typedef struct List//列出单链表的管理方式
{
PNode first;//指向头部
PNode last;//指向尾部
size_t size;//节点个数
}List;//定义单链表的类型List
void InitList(List* list)//初始化函数的实现
{
list->first = list->last = (Node*)malloc(sizeof(Node));//申请了一个节点,将头和尾部指向这个节点
assert(list->first != NULL);//检查节点是否申请成功
list->first->next = NULL;//这里必须要附为空,不然在头插时会乱码
list->size = 0;//此时元素个数为0
}
//尾插
void pushBack(List*list,ElemType x)
{
Node* s = (Node*)malloc(sizeof(Node));//申请一个节点,另s指向该节点
assert(s != NULL);
s->data = x;//将要插入的值放人该结点的data中
s->next = NULL; //将它的next指针赋空(若不赋空,则是随机值,程序报错)
list->last->next = s;
list->last = s;//将新结点链接进入list的尾部
list->size++;//元素个数加1
}
void push_front(List* list, ElemType x)
{
Node* s = (Node*)malloc(sizeof(Node));
assert(s != NULL);
s->data = x;
s->next = NULL;
s->next = list->first->next;
list->first->next = s;
list->size++;
}
void pop_back(List* list) //尾删方法
{
if (list->size == 0) //如果链表长度为0,直接返回
{
return;
}
Node* p = list->first;
while (p->next != list->last) //去寻找尾结点的前驱结点
{
p = p->next; //p最终指向尾结点的前驱结点
}
free(list->last); //释放尾结点
list->last = p; //将尾指针指向p(原尾结点的前驱结点)
list->last->next = NULL;
list->size--;
}
void pop_front(List* list) //头删方法的实现
{
if (list->size == 0) //如果链表长度为0,直接返回
{
return;
}
Node* p = list->first->next;
list->first->next = p->next; //头删比尾删简单,但应注意链表中仅有一个元素的情况
free(p);
if (list->size == 1) //如果链表仅有一个元素,删除后,其尾首指针都应指向头结点
{
list->last = list->first;
}
list->size--;
}
void insert_val(List* list, ElemType x) //按值插入函数的实现:前提是在链表有序的条件下按值插入
{
Node* s = (Node*)malloc(sizeof(Node)); //创建一个新结点
assert(s != NULL);
s->data = x; //这里已经将要插入的值放入新结点中
s->next = NULL;
Node* p = list->first;
while (p->next != NULL && p->next->data < x) //创建了新指针p去寻找s结点该插入的位置
{
p = p->next;
}
if (p->next == NULL) //在尾部插入的情况
{
list->last = s;
}
s->next = p->next;
p->next = s;
list->size++;
}
Node* find(List* list, ElemType x)
{
Node* p = list->first->next;
while (p != NULL && p->data != x)
{
p = p->next;
}
return p;
}
void clear(List* list) //链表清除函数的实现
{
if (list->size == 0)
{
return;
}
Node* p = list->first->next; //p始终指向头结点的下一结点
while (p != NULL) //遍历元素,如果
{
list->first->next = p->next; //若到达最后一个元素,则其p->next为空则可退出循环
free(p); //释放p所指向的结点
p = list->first->next;
}
list->last = list->first;
list->size = 0;
}
void destory(List* list)//摧毁链表函数的实现
{
clear(list);//先将链表清除
free(list->first);
list->first = list->last = NULL;
list->size = 0;
}