1.链表概念
链表是一种数据结构,由一系列节点组成,每个节点包含数据域和指针域,指针域是指向下一个节点的指针。最后一个节点的指针为空。
2.单链表实现
单链表且不带头节点的链表。如下图2.1头文件及数据类型定义
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
//类型重定义
typedef int SListData_t;
//节点
typedef struct SListNode {
SListData_t data;
struct SListNode* next;
}SLTNode;
2.2单链表接口函数
//函数声明
void printSL(SLTNode* phead); //打印
void SListPushBack(SLTNode** pphead, SListData_t x); //尾插
void SListPushFront(SLTNode** pphead,SListData_t x); //头插
void SListPopBack(SLTNode** pphead); //尾删
void SListPopFront(SLTNode** phead); //头删
SLTNode* CreatListNode(SListData_t x); //创建新节点
SLTNode* SListFind(SLTNode* phead, SListData_t x); //查找
void SListInsert(SLTNode** pphead,SLTNode* pos,SListData_t x); //在pos位置之前插入节点
void SListInsertAfter(SLTNode* pos, SListData_t x); //在pos位置后面插入节点
void SListErase(SLTNode** pphead,SLTNode* pos); //在pos位置之前删除节点
void SListEraseAfter(SLTNode* pos); //在pos位置后删除节点
void SListDestroy(SLTNode** pphead); //销毁链表
2.3接口函数实现
//打印
void printSL(SLTNode *phead)
{
SLTNode* cur = phead;
while (cur != NULL) {
printf("%d->",cur->data);
cur = cur->next;
}
printf("NULL\n");
}
//创建节点
SLTNode* CreatListNode(SListData_t x)
{
SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
if (newnode == NULL)
{
printf("malloc fail\n");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
return newnode;
}
//尾插
void SListPushBack(SLTNode **pphead, SListData_t x)
{
SLTNode* newnode = CreatListNode(x);
if (*pphead == NULL)
{
*pphead = newnode;
}
else {
//找到尾节点
SLTNode* tail = *pphead;
while (tail->next != NULL) {
tail = tail->next;
}
tail->next = newnode;
}
}
//头插
void SListPushFront(SLTNode** pphead, SListData_t x)
{
SLTNode* newnode = CreatListNode(x);
newnode->next = *pphead;
*pphead = newnode;
}
//头删
void SListPopFront(SLTNode** pphead)
{
SLTNode* cur = NULL;
cur = *pphead;
if (cur == NULL)
{
return;
}
else {
*pphead = cur->next;
free(cur);
cur->data = 0;
cur->next = NULL;
}
}
//尾删
void SListPopBack(SLTNode** pphead)
{
if (*pphead == NULL)
{
return;
}
SLTNode* cur = *pphead;
SLTNode* cur_head = NULL;
if ((*pphead == NULL))
{
free(*pphead);
*pphead = NULL;
}
else
{
while (cur->next != NULL)
{
cur_head = cur;
cur = cur->next;
}
free(cur);
cur = NULL;
cur_head->next = NULL;
}
}
//查找
SLTNode* SListFind(SLTNode* phead, SListData_t x)
{
SLTNode* cur = phead;
while (cur)
{
if (cur->data == x)
{
return cur;
}
else {
cur = cur->next;
}
}
return NULL;
}
//在pos位置之前插入节点
void SListInsert(SLTNode** pphead, SLTNode* pos, SListData_t x)
{
SLTNode* newnode = CreatListNode(x);
if (*pphead != pos)
{
//找到pos前一个位置
SLTNode* posPrev = *pphead;
while (posPrev->next != pos)
{
posPrev = posPrev->next;
}
posPrev->next = newnode;
newnode->next = pos;
}
else
{
newnode->next = *pphead;
*pphead = newnode;
}
}
//在pos节点后面插入节点
void SListInsertAfter(SLTNode* pos, SListData_t x)
{
SLTNode* newnode = CreatListNode(x);
newnode->next = pos->next;
pos->next = newnode;
}
//在pos位置之前删除节点
void SListErase(SLTNode** pphead, SLTNode* pos)
{
if (*pphead == pos)
{
pphead = pos->next;
free(pos);
}
else {
SLTNode* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
prev->next = pos->next;
free(pos);
pos = NULL;
}
}
//在pos位置后删除节点
void SListEraseAfter(SLTNode* pos)
{
assert(pos->next);
SLTNode* pos_next = pos->next;
pos->next = pos_next->next;
free(pos_next);
pos_next = NULL;
}
//销毁链表
void SListDestroy(SLTNode** pphead)
{
SLTNode* cur = *pphead;
while (cur)
{
SLTNode* next = cur->next;
free(cur);
cur = next;
}
*pphead = NULL;
}
2.4测试
void TestSList1()
{
SLTNode* plist = NULL;
SListPushBack(&plist,1);
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
SListPushBack(&plist, 4);
SLTNode* pos1 = SListFind(plist,1);
printSL(plist);
//printf("pos1->data = %d\n",pos1->data);
SListInsert(&plist,pos1,168);
SListEraseAfter(pos1);
printSL(plist);
}
int main()
{
TestSList1();
return 0;
}