单链表:概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。
1.创建存储数据的data。
2.创建结构体指针next。
1.申请一块空间,如果空间申请失败则退出系统,成功则返回新结点。
1.判断链表是否为空,如果链表为空,让头指针指向新的结点
2.如果链表不为空,查找链表的尾结点,让尾结点的next指针指向新结点
单链表的头插有以下几个操作:
1.让新结点的next指针指向头。
2.让头指针指向新的结点。
1.对传进来的头指针进行断言操作。
2.判断链表是否只有一个元素,如果只有一个元素,释放掉头指针指向的空间,并让头指针指向空。
3.如果链表有多个元素,找到链表的倒数第二个结点,将尾结点的空间释放,让倒数第二个结点的next指针置空,使其变成尾结点。
1.对传进来的指针进行断言操作。
2.保留第一个结点的next指针的地址。
3.释放第一个结点的空间。
4.让头指针指向第一个节点的next指针。
1.让cur等于第一个结点的地址,当cur走到空时,即打印结束。
1.插入的位置在头的前面,本质就是进行头插。
2.插入的位置在中间,找到插入位置的前一个结点,让这个结点的next指针指向新结点,让新结点的next指针指向位置pos。
1.删除的位置在头部,保留第一个结点next指针,让头指针指向这个指针。释放掉原来第一个结点的空间。
2.删除的位置不在头部,找到删除位置的第一个结点,让前一个结点的next指针指向删除位置的下一个结点,释放掉要删除的位置的空间。
单链表在传参的时候,因为头指针的指向随时变化,所以在传递的时候需要传递头指针的地址,形参就需要用二级指针进行接收。
#pragma once
#include
#include
#include
typedef int SLTdatatype;
typedef struct Slistnode {
SLTdatatype data;
struct Slistnode* next;
}Slistnode;
void Slistpushback(Slistnode **pphead,SLTdatatype x);//单链表的尾插
void Slistprint(Slistnode* phead);//单链表的打印
void Slistpopfront(Slistnode** pphead);//单链表的头删
void Slistpopback(Slistnode** pphead);//单链表的尾删
void Slistpushfront(Slistnode** pphead,SLTdatatype x);//单链表的头插
Slistnode* Slistfind(Slistnode* pphead,SLTdatatype x);//查找单链表的某个数字,并返回其所在结点的地址。
void Slistinsertbefore(Slistnode** pphead,Slistnode* pos, SLTdatatype x);//单链表的指定位置前面插入,可以和find函数接口一起使用
#include"Slist.h"
Slistnode* Buylist(SLTdatatype x) { //单链表新结点的空间申请去
Slistnode* newnode = (Slistnode*)malloc(sizeof(Slistnode));
if (newnode == NULL)
printf("空间申请失败");
newnode->data = x;
newnode->next = NULL;
}
void Slistprint(Slistnode* phead) { //单链表的打印
Slistnode* cur = phead;
while (cur->next != NULL) {
printf("%d", cur->data);
cur = cur->next;
}
printf("%d", cur->data);
//1234334
}
void Slistpushback(Slistnode** pphead, SLTdatatype x) { //单链表的尾插
Slistnode* newnode = Buylist(x);
if (*pphead == NULL) {
*pphead = newnode;
}
else {
Slistnode* tail = *pphead;
while (tail->next != NULL) {
tail = tail->next;
}
tail->next = newnode;
}
}
void Slistpushfront(Slistnode** pphead, SLTdatatype x) //单链表的头插
{
Slistnode* newnode = Buylist(x);
newnode->next = *pphead;
*pphead = newnode;
}
void Slistpopback(Slistnode** pphead) {//单链表的尾删
assert(*pphead != NULL);
if ((*pphead)->next == NULL) {
free(*pphead);
*pphead = NULL;
}
else {
Slistnode* tail = *pphead;
while (tail->next->next != NULL)
tail = tail->next;
free(tail->next);
tail->next = NULL;
}
}
void Slistpopfront(Slistnode** pphead) {//单链表的头删
//pphead存的是plist的地址,现在要将plist指向的空间free掉,然后将plist指向下一个结点
assert(*pphead != NULL);
Slistnode* next;
next = (*pphead)->next;
free(*pphead);
*pphead = next;
}
Slistnode* Slistfind(Slistnode* pphead,SLTdatatype x) { //单链表查找数字,找到数字就返回其地址,没找到就返回空
Slistnode* cur = pphead;
while (cur) {
if (cur->data == x)
return cur;
else
cur = cur->next;
}
return NULL;
}
void Slistinsertbefore(Slistnode** pphead, Slistnode* pos, SLTdatatype x) {
assert(pphead);
assert(pos);
Slistnode* cur = pos;
Slistnode* newnode = Buylist(x);
if (cur == *pphead) {
newnode->next = *pphead;
*pphead = newnode;
}
else {
Slistnode* posprev;
while (posprev->next != pos)
pos = pos->next;
posprev->next = newnode;
newnode->next = pos;
}
}
void test01() {
Slistnode* plist = NULL;
Slistpushfront(&plist, 4);
Slistinsertbefore(&plist, plist, 3);
Slistprint(plist);
}
int main() {
test01();
}