链表也是一种线性表,适用于需要频繁插入删除数据的情况
链表在逻辑上是连续的,在物理上是不连续的
链表的内存结构是不连续的内存空间,是将一组零散的内存块串联,,每个内存块被称为结点(Node),结点分为两部分:数据域和指针域。
下面实现单链表(不带头)
定义结点
//single list
typedef int SLNDataType;
typedef struct SListNode
{
SLNDataType val;
struct SListNode* next;
}SLNode;
删除
尾删
声明
形参是实参的一份临时拷贝,对形参的修改不会影响实参,故这里传二级指针
void SLPopBack(SLNode** pphead);
实现
void SLPopBack(SLNode** pphead)
{
if ((*pphead) == NULL)
{
return;
}
if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
return;
}
SLNode* prev = NULL;
SLNode* tail = *pphead;
while (tail->next!=NULL)
{
prev = tail;
tail = tail->next;
}
free(tail);
tail = NULL;
prev->next = NULL;
}
第二种方法
void SLPopBackplus(SLNode** pphead)
{
if ((*pphead) == NULL)
{
return;
}
if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
return;
}
SLNode* tail = *pphead;
while (tail->next->next != NULL)
{
tail = tail->next;
}
free(tail->next);
tail->next = NULL;
}
头删
声明
void SLPopFront(SLNode** pphead);
实现
void SLPopFront(SLNode** pphead)
{
if (*(pphead) == NULL)
{
return;
}
SLNode* newhead = (*pphead)->next;
free(*pphead);
*pphead = newhead;
return;
}
在某个位置删除
声明
void SLErase(SLNode** pphead, SLNode* pos);
实现
void SLErase(SLNode** pphead, SLNode* pos)
{
if (pos == NULL)
{
return;
}
if (*pphead == pos)
{
*pphead = pos->next;
free(pos);
pos = NULL;
return;
}
SLNode* del = *pphead;
while (del->next!=pos)
{
del = del->next;
}
del->next = pos->next;
free(pos);
pos = NULL;
return;
}
在某个位置后删除
声明
void SLTEraseAfter(SLNode* pos);
实现
void SLTEraseAfter(SLNode* pos)
{
assert(pos);
assert(pos->next);
SLNode* tmp = pos->next;
pos->next = pos->next->next;
free(tmp);
tmp = NULL;
}
插入
创建新结点函数
SLNode* CreateNode(SLNDataType x)
{
SLNode* newNode=(SLNode*)malloc(sizeof(SLNDataType));
if (newNode == NULL)
{
perror("malloc fail");
exit(-1);
}
newNode->val = x;
newNode->next = NULL;
return newNode;
}
尾插
声明
void SLPushBack(SLNode** pphead, SLNDataType x);
实现
void SLPushBack(SLNode** pphead, SLNDataType x)
{
SLNode* newNode = CreateNode(x);
if (*pphead == NULL)
{
*pphead = newNode; //改变结构体的指针,用二级指针
}
else
{
SLNode* tail = *pphead;
while (tail->next != NULL)
{
tail = tail->next;
}
tail->next = newNode; //改变结构体,用结构体指针
}
}
头插
声明
void SLPushFront(SLNode** pphead, SLNDataType x);
实现
void SLPushFront(SLNode** pphead, SLNDataType x)
{
SLNode* newNode = CreateNode(x);
newNode->next = *pphead;
*pphead = newNode;
}
在某个位置前插入
声明
void SLInsert(SLNode** pphead, SLNode* pos, SLNDataType x);
实现
void SLInsert(SLNode** pphead, SLNode* pos, SLNDataType x)
{
if (*pphead == pos)
{
SLNode* newNode = CreateNode(x);
newNode->next = *pphead;
*pphead = newNode;
return;
}
SLNode* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
SLNode* newNode = CreateNode(x);
newNode->next = pos;
prev->next = newNode;
}
在某个位置后插入
声明
void SLTInsertAfter(SLNode * pos, SLNDataType x);
实现
void SLTInsertAfter(SLNode * pos, SLNDataType x)
{
assert(pos);
SLNode* newnode = CreateNode(x);
newnode->next = pos->next;
pos->next = newnode;
}
打印
声明
void SLprint(SLNode* head);
实现
void SLprint(SLNode* head)
{
SLNode* cur = head;
if (cur == NULL)
{
printf("NULL\n");
return;
}
while (cur->next != NULL)
{
printf("%d->", cur->val);
cur = cur->next;
}
printf("%d->NULL\n", cur->val);
}
查找
声明
SLNode* SLFind(SLNode* phead,SLNDataType x);
实现
SLNode* SLFind(SLNode* phead,SLNDataType x)
{
while (phead != NULL&&phead->val != x)
{
phead = phead->next;
}
if (phead == NULL)
{
printf("查找失败\n");
return NULL;
}
else
{
printf("查找成功\n");
return phead;
}
}
销毁
声明
void SLDestroy(SLNode** pphead);
实现
void SLDestroy(SLNode** pphead)
{
SLNode* des=(*pphead)->next;
while (des&&*pphead)
{
free(*pphead);
*pphead = des;
des = des->next;
}
free(*pphead);
*pphead = NULL;
return;
}
是不是名表其意呢(不带头可能就真的跟不带头一样难),测试下来快崩溃了,感觉不带头的比带头的难好多的说(指针妹学好)
完整代码
SList.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//single list
typedef int SLNDataType;
typedef struct SListNode
{
SLNDataType val;
struct SListNode* next;
}SLNode;
void SLprint(SLNode* head);
void SLPushFront(SLNode** pphead, SLNDataType x);
void SLPushBack(SLNode** pphead, SLNDataType x);
void SLPopBack(SLNode** pphead);
void SLPopBackplus(SLNode** pphead);
void SLPopFront(SLNode** pphead);
SLNode* SLFind(SLNode* phead,SLNDataType x);
//在pos前插入
void SLInsert(SLNode** pphead,SLNode* pos, SLNDataType x);
//删除pos位置
void SLErase(SLNode** pphead,SLNode* pos);
// 后面插入 后面删除
void SLTInsertAfter(SLNode* pos, SLNDataType x);
void SLTEraseAfter(SLNode* pos);
void SLDestroy(SLNode** pphead);
SList.c
#include"SList.h"
void SLprint(SLNode* head)
{
SLNode* cur = head;
if (cur == NULL)
{
printf("NULL\n");
return;
}
while (cur->next != NULL)
{
printf("%d->", cur->val);
cur = cur->next;
}
printf("%d->NULL\n", cur->val);
}
SLNode* CreateNode(SLNDataType x)
{
SLNode* newNode=(SLNode*)malloc(sizeof(SLNDataType));
if (newNode == NULL)
{
perror("malloc fail");
exit(-1);
}
newNode->val = x;
newNode->next = NULL;
return newNode;
}
void SLPushBack(SLNode** pphead, SLNDataType x)
{
SLNode* newNode = CreateNode(x);
if (*pphead == NULL)
{
*pphead = newNode; //改变结构体的指针,用二级指针
}
else
{
SLNode* tail = *pphead;
while (tail->next != NULL)
{
tail = tail->next;
}
tail->next = newNode; //改变结构体,用结构体指针
}
}
void SLPushFront(SLNode** pphead, SLNDataType x)
{
SLNode* newNode = CreateNode(x);
newNode->next = *pphead;
*pphead = newNode;
}
void SLPopBack(SLNode** pphead)
{
if ((*pphead) == NULL)
{
return;
}
if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
return;
}
SLNode* prev = NULL;
SLNode* tail = *pphead;
while (tail->next!=NULL)
{
prev = tail;
tail = tail->next;
}
free(tail);
tail = NULL;
prev->next = NULL;
}
void SLPopBackplus(SLNode** pphead)
{
if ((*pphead) == NULL)
{
return;
}
if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
return;
}
SLNode* tail = *pphead;
while (tail->next->next != NULL)
{
tail = tail->next;
}
free(tail->next);
tail->next = NULL;
}
void SLPopFront(SLNode** pphead)
{
if (*(pphead) == NULL)
{
return;
}
SLNode* newhead = (*pphead)->next;
free(*pphead);
*pphead = newhead;
return;
}
SLNode* SLFind(SLNode* phead,SLNDataType x)
{
while (phead != NULL&&phead->val != x)
{
phead = phead->next;
}
if (phead == NULL)
{
printf("查找失败\n");
return NULL;
}
else
{
printf("查找成功\n");
return phead;
}
}
void SLInsert(SLNode** pphead, SLNode* pos, SLNDataType x)
{
if (*pphead == pos)
{
SLNode* newNode = CreateNode(x);
newNode->next = *pphead;
*pphead = newNode;
return;
}
SLNode* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
SLNode* newNode = CreateNode(x);
newNode->next = pos;
prev->next = newNode;
}
void SLErase(SLNode** pphead, SLNode* pos)
{
if (pos == NULL)
{
return;
}
if (*pphead == pos)
{
*pphead = pos->next;
free(pos);
pos = NULL;
return;
}
SLNode* del = *pphead;
while (del->next!=pos)
{
del = del->next;
}
del->next = pos->next;
free(pos);
pos = NULL;
return;
}
void SLDestroy(SLNode** pphead)
{
SLNode* des=(*pphead)->next;
while (des&&*pphead)
{
free(*pphead);
*pphead = des;
des = des->next;
}
free(*pphead);
*pphead = NULL;
return;
}
void SLTEraseAfter(SLNode* pos)
{
assert(pos);
assert(pos->next);
SLNode* tmp = pos->next;
pos->next = pos->next->next;
free(tmp);
tmp = NULL;
}
void SLTInsertAfter(SLNode * pos, SLNDataType x)
{
assert(pos);
SLNode* newnode = CreateNode(x);
newnode->next = pos->next;
pos->next = newnode;
}
test.c
#include"SList.h"
void Test1()
{
SLNode* s1=NULL;
SLPushBack(&s1,1);
SLPushBack(&s1,2);
SLPushBack(&s1,3);
SLPushBack(&s1,4);
SLprint(s1);
return;
}
void Test2()
{
SLNode* s1 = NULL;
SLPushFront(&s1, 1);
SLPushFront(&s1, 2);
SLPushFront(&s1, 3);
SLPushFront(&s1, 4);
SLprint(s1);
return;
}
void Test3()
{
SLNode* s1 = NULL;
SLPushFront(&s1, 1);
SLPushFront(&s1, 2);
SLPushFront(&s1, 3);
SLPushFront(&s1, 4);
SLprint(s1);
SLPopBack(&s1);
SLprint(s1);
SLPopBack(&s1);
SLprint(s1);
SLPopBack(&s1);
SLprint(s1);
SLPopBack(&s1);
SLprint(s1);
SLPopBack(&s1);
SLprint(s1);
return;
}
void Test4()
{
SLNode* s1 = NULL;
SLPushFront(&s1, 1);
SLPushFront(&s1, 2);
SLPushFront(&s1, 3);
SLPushFront(&s1, 4);
SLprint(s1);
SLPopBackplus(&s1);
SLprint(s1);
SLPopBackplus(&s1);
SLprint(s1);
SLPopBackplus(&s1);
SLprint(s1);
SLPopBackplus(&s1);
SLprint(s1);
SLPopBackplus(&s1);
SLprint(s1);
return;
}
void Test5()
{
SLNode* s1 = NULL;
SLPushFront(&s1, 1);
SLPushFront(&s1, 2);
SLPushFront(&s1, 3);
SLPushFront(&s1, 4);
SLprint(s1);
SLPopFront(&s1);
SLprint(s1);
SLPopFront(&s1);
SLprint(s1);
SLPopFront(&s1);
SLprint(s1);
SLPopFront(&s1);
SLprint(s1);
SLPopFront(&s1);
SLprint(s1);
return;
}
void Test6()
{
SLNode* s1 = NULL;
SLPushBack(&s1, 1);
SLPushBack(&s1, 2);
SLPushBack(&s1, 3);
SLPushBack(&s1, 4);
SLprint(s1);
SLFind(s1, 1);
SLFind(s1, 5);
SLFind(s1, 9);
SLFind(s1, 4);
return;
}
void Test7()
{
SLNode* s1 = NULL;
SLPushBack(&s1, 1);
SLPushBack(&s1, 2);
SLPushBack(&s1, 3);
SLPushBack(&s1, 4);
SLprint(s1);
SLNode* a = SLFind(s1, 1);
SLInsert(&s1, a , 9);
SLprint(s1);
SLNode* b=SLFind(s1, 4);
SLInsert(&s1, b, 8);
SLprint(s1);
return;
}
void Test8()
{
SLNode* s1 = NULL;
SLPushBack(&s1, 1);
SLPushBack(&s1, 2);
SLPushBack(&s1, 3);
SLPushBack(&s1, 4);
SLprint(s1);
SLNode* a = SLFind(s1,0 );
SLErase(&s1, a);
SLprint(s1);
SLNode* d = SLFind(s1, 2);
SLErase(&s1, d);
SLprint(s1);
SLNode* b = SLFind(s1, 4);
SLErase(&s1, b);
SLprint(s1);
return;
}
void Test9()
{
SLNode* s1 = NULL;
SLPushBack(&s1, 1);
SLPushBack(&s1, 2);
SLPushBack(&s1, 3);
SLPushBack(&s1, 4);
SLprint(s1);
SLDestroy(&s1);
SLprint(s1);
return;
}
int main()
{
Test9();
return 0;
}
带头的好好写:
#include<stdio.h>
#include<stdlib.h>
//定义单链表
typedef struct Node
{
int data;
struct Node* next;
}Node;
//初始化
Node* initList()
{
Node* list = (Node*)malloc(sizeof(Node));
list->data = 0;
list->next = NULL;
return list;
}
//头插
void headInsert(Node* list, int data)
{
Node* node = (Node*)malloc(sizeof(Node));
node->data = data;
node->next = list->next;
list->next = node;
list->data++;
}
//尾插
void tailInsert(Node* list, int data)
{
Node* head = list;
Node* node = (Node*)malloc(sizeof(Node));
node->data = data;
node->next = NULL;
list = list->next;
while (list->next)
{
list = list->next;
}
list->next = node;
head->data++;
}
//删除
void delete(Node* list, int data)
{
Node* pre = list;
Node* current = list->next;
while (current)
{
if (current->data == data)
{
pre->next = current->next;
free(current);
current = NULL;
break;
}
pre = current;
current = current->next;
}
list->data--;
}
//遍历
void PrintList(Node* list)
{
list = list->next;
while (list)
{
printf("%d", list->data);
list = list->next;
}
printf("\n");
}
Node* ReverseList(Node* head)
{
if (head == NULL)
{
return NULL;
}
else
{
Node* new = head;
Node* pre = head;
while (new->next != NULL)
{
new = new->next;
}
Node* new1 = new;
for (int i = 0; i < head->data - 1; i++)
{
while (pre->next != new)
{
pre = pre->next;
}
new->next = pre;
new = pre;
pre = head;
}
new->next = NULL;
head->next = NULL;
pre->next = NULL;
pre->data = head->data;
Node* new2 = malloc(sizeof(Node));
new2->data = head->data;
new2->next = new1;
return new2;
}
}
int main()
{
Node* list = initList();
headInsert(list, 1);
headInsert(list, 2);
headInsert(list, 3);
headInsert(list, 4);
PrintList(list);
Node* p=ReverseList(list);
PrintList(p);
}