前言
提示:个人学习/复习 笔记使用,仅供参考
一、单链表
概念
链表是一种物理存储结构上不连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的,可以实现更加灵活的动态内存管理。
链表在物理结构上不一定是线性的,而在逻辑结构上是线性的
链表的构成
链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。
每个结点包括两个部分:
1、数据域:存储数据元素
2、指针域:存储下一个结点地址
链表的定义
//无头非循环单链表
typedef int SingleListDataType;
typedef struct SingleList {
SingleListDataType data; //数据域
struct SingleList* next; //指针域
}SingleList;
注意:下面接口中,如需修改链表的内容,则传二级指针
二、申请节点
//申请节点
SingleList* BuySingleListNode(SingleListDataType x) {
SingleList* newNode = (SingleList*)malloc(sizeof(SingleList));
if (newNode==NULL) {
perror("malloc");
return NULL;
}
newNode->data = x;
newNode->next = NULL;
return newNode;
};
三、打印链表
//打印
void SingleListPrint(SingleList* ps) { //打印不会修改链表,所以一级指针就行
if (ps==NULL) {
printf("空链表\n");
}
else {
while (ps!=NULL) {
printf("%d->",ps->data);
ps = ps->next;
}
printf("NULL\n");
}
};
四、尾插
//尾插
void SingleListPushBack(SingleList** pps, SingleListDataType x) {
assert(pps);
SingleList* newNode = BuySingleListNode(x);
if (*pps ==NULL) { //如果单链表为空,直接就插入了
*pps = newNode;
}
else { //如果单链表不为空,需要遍历找到尾,再插入
SingleList* tail = *pps;
while (tail->next != NULL) {
tail = tail->next;
}
tail->next = newNode;
}
};
五、尾删
//尾删
void SingleListPopBack(SingleList** pps) {
assert(pps);
if (*pps ==NULL) {
printf("链表为空\n");
}
else {
SingleList* tail = *pps;
SingleList* prev = tail;
while (tail->next!=NULL) {
prev = tail;
tail = tail->next;
}
prev->next = NULL;
}
};
六、头插
//头插
void SingleListPushFront(SingleList** pps, SingleListDataType x) {
assert(pps);
SingleList* newNode = BuySingleListNode(x);
if (*pps ==NULL) {
*pps = newNode;
}
else {
SingleList* next = (*pps);
*pps = newNode;
newNode->next=next;
}
};
七、头删
//头删
void SingleListPopFront(SingleList** pps) {
if (*pps ==NULL) {
printf("空链表\n");
return;
}
else {
*pps = (*pps)->next;
}
};
八、指定位置后插入
//指定位置结点后插入
void SingleListInsertAfter(SingleList** pps, int pos, SingleListDataType x) {
assert(pps);
assert(*pps);
SingleList* cur = *pps;
SingleList* newNode = BuySingleListNode(x);
while (--pos) {
cur = cur->next;
}
newNode->next = cur->next;
cur->next = newNode;
};
九、指定位置后删除
//指定位置结点后删除
void SingleListEraseAfter(SingleList** pps, int pos) {
assert(pps);
assert(*pps);
SingleList* cur = *pps;
while (--pos) {
cur = cur->next;
}
cur->next = cur->next->next;
};
十、指定位置删除
//删除指定位置节点
void SingleListErase(SingleList** pps, int pos) {
assert(pps);
assert(*pps);
SingleList* cur = *pps;
SingleList* prev = *pps;
while (--pos) {
prev = cur;
cur = cur->next;
}
prev->next = cur->next;
};
十一、查找指定值,返回地址
//查找指定值,返回地址
void SingleListFind(SingleList** pps, int x) {
assert(pps);
assert(*pps);
SingleList* cur = *pps;
while (cur!=NULL) {
if (x==cur->data) {
return cur;
}
cur = cur->next;
}
return NULL;
};
十二、求链表长度
//返回链表长度
int SingleListSize(SingleList* ps) {
SingleList* cur = ps;
int count = 0;
while (cur != NULL) {
count++;
cur = cur->next;
}
return count;
};
十三、销毁
//销毁
void SingleListDestory(SingleList** pps) {
assert(pps);
SingleList* cur = *pps;
SingleList* next = *pps;
while (cur!=NULL) {
next = cur->next;
free(cur);
cur = next;
}
*pps = NULL;
};