SingleList.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int ElementType;
typedef struct ListNode
{
ElementType data;
struct ListNode* next;
}ListNode, *SingleList;
// 初始化单链表
void ListInit(ListNode** pphead);
// 创建一个新的节点
ListNode* CreateNewnode(ElementType e);
// 尾部插入
int ListPushBack(ListNode** pphead, ElementType e);
// 打印链表
void ListPrint(ListNode* phead);
// 头部插入
int ListPushFront(ListNode** pphead, ElementType e);
// 判空
int ListEmpty(ListNode* phead);
// 销毁
int ListDestroy(ListNode** pphead);
// 清空
int ListClear(ListNode** pphead);
// 表长
int ListLength(ListNode* phead);
// 尾删
int ListPopBack(ListNode** pphead);
// 头删
int ListPopFront(ListNode** pphead);
// 按位置插入(pos为逻辑位序,pos==1相当于头插,pos==length+1相当于尾插)
int ListInsertByPos(ListNode** pphead, int pos, ElementType e);
// 按位置删除(pos为逻辑位序,pos==1相当于头删,pos==length相当于尾删)
int ListDeleteByPos(ListNode** pphead, int pos);
// 按值查找,返回找到后的节点
ListNode* ListFind(ListNode* phead, ElementType e);
// 按值删除
int ListDeleteByVal(ListNode** pphead, ElementType e);
// 在pos位置之前去插入一个节点
int ListInsert(ListNode** pphead, ListNode* pos, ElementType e);
// 在pos位置之后去插入一个节点
int ListInsertAfter(ListNode* pos, ElementType e);
// 删除pos节点
int ListDelete(ListNode** pphead, ListNode* pos);
// 在pos节点之后删除一个节点
int ListDeleteAfter(ListNode* pos);
SingleList.c
#define _CRT_SECURE_NO_WARNINGS
#include "SingleList.h"
// 初始化单链表
void ListInit(ListNode** pphead)
{
assert(pphead);
*pphead = NULL;
}
// 创建一个新的节点
ListNode* CreateNewnode(ElementType e)
{
ListNode* newnode = (ListNode*)malloc(sizeof(struct ListNode));
if (newnode == NULL)
{
exit(-1);
}
newnode->data = e;
newnode->next = NULL;
return newnode;
}
// 尾部插入
int ListPushBack(ListNode** pphead, ElementType e)
{
assert(pphead);
// 创建一个新的节点
ListNode* newnode = CreateNewnode(e);
// 1.空表
if (*pphead == NULL)
{
*pphead = newnode;
return 1;
}
// 2.非空表
// 找尾
ListNode* tail = *pphead;
while (tail->next)
{
tail = tail->next;
}
tail->next = newnode;
return 1;
}
// 打印链表
void ListPrint(ListNode* phead)
{
ListNode* cur = phead;
while (cur)
{
printf("%d->", cur->data);
cur = cur->next;
}
printf("NULL\n");
}
// 头部插入
int ListPushFront(ListNode** pphead, ElementType e)
{
assert(pphead);
// 创建一个新的节点
ListNode* newnode = CreateNewnode(e);
newnode->next = *pphead;
*pphead = newnode;
return 1;
}
// 判空
int ListEmpty(ListNode* phead)
{
return phead == NULL;
}
// 销毁
int ListDestroy(ListNode** pphead)
{
assert(pphead);
while (*pphead)
{
ListNode* p = *pphead;
*pphead = p->next;
free(p);
}
*pphead = NULL;
return 1;
}
// 清空
int ListClear(ListNode** pphead)
{
assert(pphead);
return ListDestroy(pphead);
}
// 表长
int ListLength(ListNode* phead)
{
ListNode* cur = phead;
int count = 0;
while (cur)
{
count++;
cur = cur->next;
}
return count;
}
// 尾删
int ListPopBack(ListNode** pphead)
{
assert(pphead);
// 链表为空时
assert(*pphead);
ListNode* tail = *pphead;
ListNode* prev = NULL;
// 链表只有一个节点时
if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
return 1;
}
else
{
// 链表有两个或者以上节点时
while (tail->next)
{
prev = tail;
tail = tail->next;
}
free(tail);
tail = NULL;
prev->next = NULL;
return 1;
}
}
// 头删
int ListPopFront(ListNode** pphead)
{
assert(pphead);
// 链表为空时
assert(*pphead);
ListNode* next = (*pphead)->next;
free(*pphead);
*pphead = next;
return 1;
}
// 按位置插入(pos为逻辑位序,pos==1相当于头插,pos==length+1相当于尾插)
int ListInsertByPos(ListNode** pphead, int pos, ElementType e)
{
assert(pphead);
assert(pos >= 1 && pos <= ListLength(*pphead) + 1);
// 创建一个新的节点
ListNode* newnode = CreateNewnode(e);
// 相当于头插
if (pos == 1)
{
return ListPushFront(pphead, e);
}
// 找到pos的前一个节点
ListNode* prev = *pphead;
int i = 0;
for (i = 1; i < pos - 1; i++)
{
prev = prev->next;
}
newnode->next = prev->next;
prev->next = newnode;
return 1;
}
// 按位置删除(pos为逻辑位序,pos==1相当于头删,pos==length相当于尾删)
int ListDeleteByPos(ListNode** pphead, int pos)
{
assert(pphead);
assert(pos >= 1 && pos <= ListLength(*pphead));
// 判空
if (ListEmpty(*pphead))
{
return 0;
}
// 相当于头删
if (pos == 1)
{
return ListPopFront(pphead);
}
// 找到pos的前一个节点
ListNode* prev = *pphead;
int i = 0;
for (i = 1; i < pos - 1; i++)
{
prev = prev->next;
}
ListNode* p = prev->next;
prev->next = p->next;
free(p);
return 1;
}
// 按值查找,返回找到后的节点,找不到返回NULL
ListNode* ListFind(ListNode* phead, ElementType e)
{
ListNode* cur = phead;
while (cur)
{
if (cur->data == e)
{
return cur;
}
else
{
cur = cur->next;
}
}
return NULL;
}
// 按值删除
int ListDeleteByVal(ListNode** pphead, ElementType e)
{
assert(pphead);
if (ListEmpty(*pphead))
{
printf("链表为空!\n");
return 0;
}
// 头删
if ((*pphead)->data == e)
{
return ListPopFront(pphead);
}
ListNode* p = ListFind(*pphead, e);
// 要删除的不存在
if (p == NULL)
{
return 0;
}
ListNode* q = *pphead;
while (q->next != p)
{
q = q->next;
}
q->next = p->next;
free(p);
return 1;
}
// 在pos位置之前去插入一个节点
int ListInsert(ListNode** pphead, ListNode* pos, ElementType e)
{
assert(pphead);
assert(*pphead);
// 创建一个新的节点
ListNode* newnode = CreateNewnode(e);
if (*pphead == pos)
{
newnode->next = *pphead;
*pphead = newnode;
return 1;
}
// 找到pos的前一个节点
ListNode* posPrev = *pphead;
while (posPrev->next != pos)
{
posPrev = posPrev->next;
}
posPrev->next = newnode;
newnode->next = pos;
return 1;
}
// 在pos位置之后去插入一个节点
int ListInsertAfter(ListNode* pos, ElementType e)
{
// 创建一个新的节点
ListNode* newnode = CreateNewnode(e);
newnode->next = pos->next;
pos->next = newnode;
return 1;
}
// 删除pos节点
int ListDelete(ListNode** pphead, ListNode* pos)
{
assert(pphead);
if (*pphead == pos)
{
*pphead = pos->next;
free(pos);
pos = NULL;
return 1;
}
// 找到pos前一个节点
ListNode* posPrev = *pphead;
while (posPrev->next != pos)
{
posPrev = posPrev->next;
}
posPrev->next = pos->next;
free(pos);
pos = NULL;
return 1;
}
// 在pos节点之后删除一个节点
int ListDeleteAfter(ListNode* pos)
{
// pos节点之后要有元素
assert(pos->next);
ListNode* next = pos->next;
pos->next = next->next;
free(next);
next = NULL;
return 1;
}
test.c
下面是对每个接口的测试
#define _CRT_SECURE_NO_WARNINGS
#include "SingleList.h"
// 测试尾部插入
void TestList01()
{
ListNode* list;
ListInit(&list);
ListPushBack(&list, 1);
ListPushBack(&list, 2);
ListPushBack(&list, 3);
ListPushBack(&list, 4);
ListPrint(list);
}
// 测试头部插入
void TestList02()
{
ListNode* list;
ListInit(&list);
ListPushFront(&list, 1);
ListPushFront(&list, 2);
ListPushFront(&list, 3);
ListPushFront(&list, 4);
ListPrint(list);
}
// 测试链表长度
void TestList03()
{
ListNode* list;
ListInit(&list);
ListPushBack(&list, 1);
ListPushBack(&list, 2);
ListPushBack(&list, 3);
ListPushBack(&list, 4);
int count = ListLength(list);
printf("count = %d\n", count);
}
// 测试尾删
void TestList04()
{
ListNode* list;
ListInit(&list);
ListPushBack(&list, 1);
ListPushBack(&list, 2);
ListPushBack(&list, 3);
ListPushBack(&list, 4);
ListPrint(list);
ListPopBack(&list);
ListPopBack(&list);
ListPopBack(&list);
ListPrint(list);
}
// 头删
void TestList05()
{
ListNode* list;
ListInit(&list);
ListPushBack(&list, 1);
ListPushBack(&list, 2);
ListPushBack(&list, 3);
ListPushBack(&list, 4);
ListPrint(list);
ListPopFront(&list);
ListPopFront(&list);
ListPrint(list);
}
// 测试按位置插入(pos为逻辑位序,pos==1相当于头插,pos==length+1相当于尾插)
void TestList06()
{
ListNode* list;
ListInit(&list);
ListPushBack(&list, 1);
ListPushBack(&list, 2);
ListPushBack(&list, 3);
ListPushBack(&list, 4);
ListPrint(list);
ListInsertByPos(&list, 0, 33);
ListPrint(list);
}
// 测试按位置删除(pos为逻辑位序,pos==1相当于头删,pos==length相当于尾删)
void TestList07()
{
ListNode* list;
ListInit(&list);
ListPushBack(&list, 1);
ListPushBack(&list, 2);
ListPushBack(&list, 3);
ListPushBack(&list, 4);
ListPrint(list);
ListDeleteByPos(&list, 3);
ListPrint(list);
}
// 测试按值查找,返回找到后的节点,找不到返回NULL
void TestList08()
{
ListNode* list;
ListInit(&list);
ListPushBack(&list, 1);
ListPushBack(&list, 2);
ListPushBack(&list, 3);
ListPushBack(&list, 4);
ListPrint(list);
ListNode* ret = ListFind(list, 4);
if (ret != NULL)
{
printf("%d\n", ret->data);
}
// 修改值
ret->data = 44;
ListPrint(list);
}
// 测试按值删除
void TestList09()
{
ListNode* list;
ListInit(&list);
ListPushBack(&list, 1);
ListPushBack(&list, 2);
ListPushBack(&list, 3);
ListPushBack(&list, 4);
ListPrint(list);
ListDeleteByVal(&list, 6);
ListPrint(list);
}
// 测试在pos位置之前去插入一个节点
void TestList10()
{
ListNode* list;
ListInit(&list);
ListPushBack(&list, 1);
ListPushBack(&list, 2);
ListPushBack(&list, 3);
ListPushBack(&list, 4);
ListPrint(list);
ListNode* p = ListFind(list, 4);
if (p != NULL)
{
ListInsert(&list, p, 33);
}
else
{
printf("节点不存在!\n");
}
ListPrint(list);
}
void TestList11()
{
ListNode* list;
ListInit(&list);
ListPushBack(&list, 1);
ListPushBack(&list, 2);
ListPushBack(&list, 3);
ListPushBack(&list, 4);
ListPrint(list);
ListNode* p = ListFind(list, 3);
if (p != NULL)
{
ListInsertAfter(p, 11);
}
else
{
printf("节点不存在!\n");
}
ListPrint(list);
}
// 测试删除pos节点
void TestList12()
{
ListNode* list;
ListInit(&list);
ListPushBack(&list, 1);
ListPushBack(&list, 2);
ListPushBack(&list, 3);
ListPushBack(&list, 4);
ListPrint(list);
ListNode* p = ListFind(list, 3);
if (p != NULL)
{
ListDelete(&list, p);
}
else
{
printf("节点不存在!\n");
}
ListPrint(list);
}
// 测试在pos节点之后删除一个节点
void TestList13()
{
ListNode* list;
ListInit(&list);
ListPushBack(&list, 1);
ListPushBack(&list, 2);
ListPushBack(&list, 3);
ListPushBack(&list, 4);
ListPrint(list);
ListNode* p = ListFind(list, 3);
if (p != NULL)
{
ListDeleteAfter(p);
}
else
{
printf("节点不存在!\n");
}
ListPrint(list);
}
int main()
{
TestList13();
return 0;
}