链表是一种物理存储结构上非连续的、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现
1、单向、双向
2、带头、不带头
3、循环、非循环
共有八种结构
常见链表分别是无头单向非循环链表和带头双向循环链表
1、无头单向非循环链表
常作为其他结构的底层结构,如哈希桶、图的邻接表
2、带头双向循环链表
结构最复杂,实际使用的链表数据结构。
无头单向非循环链表
//带头结点的单向非循环链表
typedef int SLTDataType;
typedef struct SListNode
{
SLTDataType data;
struct SListNode *next;
}SListNode;
typedef struct SList
{
SListNode *head;
}SList;
SList.h
#ifndef _SLIST_H_
#define _SLIST_H_
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
//带头结点的单向非循环链表
typedef int SLTDataType;
typedef struct SListNode
{
SLTDataType data;
struct SListNode *next;
}SListNode;
typedef struct SList
{
SListNode *head;
}SList;
//初始化
void SListInit(SList *plist);
//销毁
void SListDestory(SList *plist);
//为x申请结点
SListNode* BuySListNode(SLTDataType x);
//头插
void SListPushFront(SList *plist, SLTDataType x);
//头删
void SListPopFront(SList *plist);
//尾插
void SListPushBack(SList *plist, SLTDataType x);
//尾删
void SListPopBack(SList *plist);
//在pos位置之后插入
void SListInsertAfter(SList *plist, SListNode *pos, SLTDataType x);
//在pos位置之前插入
void SListInsertBefore(SList *plist, SListNode *pos, SLTDataType x);
//删除pos结点
void SListErasePos(SListNode *pos);
//查找元素x
SListNode* SListFind(SList *plist, SLTDataType x);
//删除元素x
void SListEraseX(SList *plist, SLTDataType x);
//修改值
void SListModify(SListNode *pos, SLTDataType x);
//打印
void SListPrint(SList *plist);
#endif //_SLITS_H_
SList.c
#include "SList.h"
//初始化
void SListInit(SList *plist)
{
assert(plist);
plist->head = NULL;
}
//销毁
void SListDestory(SList *plist)
{
assert(plist);
SListNode *cur = plist->head;
SListNode *next;
while (cur)
{
next = cur->next;
free(cur);
cur = next;
}
plist->head = NULL;
}
//为x申请结点
SListNode* BuySListNode(SLTDataType x)
{
SListNode *node = (SListNode *)malloc(sizeof(SListNode));
assert(node);
node->data = x;
node->next = NULL;
return node;
}
//头插
void SListPushFront(SList *plist, SLTDataType x)
{
assert(plist);
SListNode *node = BuySListNode(x);
assert(node);
node->next = plist->head;
plist->head = node;
}
//头删
void SListPopFront(SList *plist)
{
assert(plist);
assert(plist->head);
SListNode *cur = plist->head;
plist->head = plist->head->next;
free(cur);
cur = NULL;
}
//尾插
void SListPushBack(SList *plist, SLTDataType x)
{
assert(plist);
if (plist->head == NULL)
{
SListPushFront(plist, x);
return;
}
SListNode *cur;
for (cur = plist->head; cur->next != NULL; cur = cur->next)
{
}
SListNode *node = BuySListNode(x);
cur->next = node;
}
//尾删
void SListPopBack(SList *plist)
{
assert(plist);
assert(plist->head);
if (plist->head->next == NULL)
{
SListPopFront(plist);
return;
}
SListNode *cur = plist->head;
while (cur->next->next != NULL)
{
cur = cur->next;
}
free(cur->next);
cur->next = NULL;
}
//在pos位置之后插入
void SListInsertAfter(SList *plist, SListNode *pos, SLTDataType x)
{
assert(plist);
SListNode *node = BuySListNode(x);
node->next = pos->next;
pos->next = node;
}
//在pos位置之前插入
void SListInsertBefore(SList *plist, SListNode *pos, SLTDataType x)
{
assert(plist);
SListNode *cur = plist->head;
while (cur->next != pos)
{
cur = cur->next;
}
SListNode *node = BuySListNode(x);
node->next = cur->next;
cur->next = node;
}
//删除pos结点
void SListErasePos(SListNode *pos)
{
SListNode *cur = pos->next;
pos->next = cur->next;
free(cur);
cur = NULL;
}
//查找元素x
SListNode* SListFind(SList *plist, SLTDataType x)
{
assert(plist);
for (SListNode *cur = plist->head; cur != NULL; cur = cur->next)
{
if (cur->data == x)
{
return cur;
}
}
return NULL;
}
//删除元素x
void SListEraseX(SList *plist, SLTDataType x)
{
assert(plist);
SListNode *pos = SListFind(plist, x);
SListErasePos(pos);
}
//修改值
void SListModify(SListNode *pos, SLTDataType x)
{
pos->data = x;
}
//打印
void SListPrint(SList *plist)
{
assert(plist);
for (SListNode *cur = plist->head; cur != NULL; cur = cur->next)
{
printf("%d --> ", cur->data);
}
printf("NULL\n");
}
main.c
#include "SList.h"
int main()
{
SList plist;
SListInit(&plist);
SListPrint(&plist);
SListPushBack(&plist, 1);
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
SListPushBack(&plist, 4);
SListPushBack(&plist, 5);
SListPushBack(&plist, 6);
SListPushBack(&plist, 7);
SListPushBack(&plist, 8);
SListPushBack(&plist, 9);
SListPushBack(&plist, 10);
SListPrint(&plist);
SListPushFront(&plist, 0);
SListPrint(&plist);
SListPopFront(&plist);
SListPrint(&plist);
SListPopBack(&plist);
SListPrint(&plist);
SListNode *pos = SListFind(&plist, 5);
SListInsertBefore(&plist, pos, 6);
SListPrint(&plist);
SListInsertAfter(&plist, pos, 4);
SListPrint(&plist);
SListErasePos(pos);
SListPrint(&plist);
SListEraseX(&plist, 3);
SListPrint(&plist);
SListDestory(&plist);
system("pause");
return 0;
}