链表是由节点组成的,我们只要创建一个个节点就可以表示链表。
用一个结构体表示一个节点:
struct Node
{
int data;
struct Node* next;
}Node;
链表的代码如下:
LinList.h
#pragma once
#include "stdio.h"
#include "assert.h"
#include "stdlib.h"
typedef int DataType;
// 不是链表的结构体
// 链表中一个结点的结构体
typedef struct Node
{
DataType data;
struct Node* next;
}Node,*pNode;
//初始化/销毁
void InitLinList(pNode* pn);
void DesLinList(pNode first);
//打印
void PrintLinList(pNode first);
//增
//头插
void PushFront(pNode* pn, DataType d);
//尾插
void PushBack(pNode* pn, DataType d);
//删
//头删
void PopFront(pNode* pn);
//尾删
void PopBack(pNode* pn);
//查找
Node* FindLinList(pNode* pn, DataType d);
// 插入,在结点 pos 前面插入
void Insert(pNode* pn, Node* pos, DataType d);
// 删除 pos 这个结点 (pos一定在链表中)
void Erase(pNode* pn, Node* pos);
// 按值删除,只删遇到的第一个
void Remove(pNode *pn, DataType d);
// 按值删除,删除所有的
void RemoveAll(pNode *pn, DataType d);
LinList.c
#define _CRT_SECURE_NO_DEPRECATE 1
#include "LinList.h"
//初始化
void InitLinList(pNode* pn)
{
assert(pn);
*pn = NULL;
}
//销毁
void DesLinList(pNode first)
{
Node* cur = first;
Node* next;
while (cur!=NULL)
{
next = cur;
cur = cur->next;
free(next);
}
}
//创建新的节点
Node* CreatNewNode(DataType d)
{
Node* node = (Node*)malloc(sizeof(Node));
node->data = d;
node->next = NULL;
return node;
}
//打印
void PrintLinList(pNode first)
{
Node* cur = first;
printf("first-->");
while (cur != NULL)
{
printf("%d-->", cur->data);
cur = cur->next;
}
printf("NULL\n");
}
//增
//头插
void PushFront(pNode* pn, DataType d)
{
assert(pn);
Node* newnode = CreatNewNode(d);
newnode->next = *pn;
*pn = newnode;
}
//尾插
void PushBack(pNode* pn, DataType d)
{
assert(pn);
Node* cur = *pn;
Node* newnode = CreatNewNode(d);
//链表为空
if (*pn==NULL)
{
*pn = newnode;
return;
}
//至少有一个数据
while (cur->next != NULL)
{
cur = cur->next;
}
cur->next = newnode;
}
//删
//头删
void PopFront(pNode* pn)
{
assert(pn);
assert(*pn);
Node* first = *pn;
*pn = (*pn)->next;
free(first);
}
//尾删
void PopBack(pNode* pn)
{
assert(pn);
assert(*pn);//没有节点
//只有一个节点
if ((*pn)->next==NULL)
{
free(*pn);
*pn = NULL;
return;
}
//至少两个节点
Node *cur = *pn;
while (cur->next->next != NULL)
{
cur = cur->next;
}
free(cur->next);
cur->next = NULL;
}
// 查找(顺序查找) 找到了,返回所在结点地址,没有找到返回 NULL
Node* FindLinList(pNode* pn, DataType d)
{
assert(pn);
Node* cur;
for (cur = *pn; cur != NULL;cur=cur->next)
{
if (cur->data==d)
{
return cur;
}
}
return NULL;
}
// 插入,在结点 pos 前面插入
void Insert(pNode* pn, Node* pos, DataType d)
{
assert(pn);
assert(pos);
if (*pn==pos)
{
PushFront(pn, d);
return;
}
Node* newnode = CreatNewNode(d);
Node*cur = *pn;
// 找到 pos 前的一个结点
while (cur->next!=pos)
{
cur = cur->next;
}
newnode->next = pos;
cur->next = newnode;
}
// 删除 pos 这个结点 (pos一定在链表中)
void Erase(pNode* pn, Node* pos)
{
assert(pn);
assert(pos);
if (*pn==pos)
{
PopFront(pn);
return;
}
Node* cur = *pn;
while (cur->next!=pos)
{
cur=cur->next;
}
cur->next = pos->next;
free(pos);
}
// 按值删除,只删遇到的第一个
void Remove(pNode *pn, DataType d)
{
assert(pn);
Node* Del = FindLinList(pn,d);
Erase(pn, Del);
}
// 按值删除,删除所有的
void RemoveAll(pNode *pn, DataType d)
{
assert(pn);
Node* cur = *pn;
Node* front = *pn;
while (cur!=NULL)
{
if (cur->data == d)
{
Node* Del = cur;
cur = cur->next;
if (Del==*pn)
{
PopFront(pn);
}
else if (Del->next==NULL)
{
PopBack(pn);
}
else
{
front->next = Del->next;
free(Del);
}
}
else
{
front = cur;
cur = cur->next;
}
}
}
test.c
#define _CRT_SECURE_NO_DEPRECATE 1
#include "LinList.h"
Node *first;
//头插
void TestPushFront()
{
InitLinList(&first);
PushFront(&first, 1);
PushFront(&first, 2);
PushFront(&first, 3);
PushFront(&first, 4);
PrintLinList(first);
}
//尾插
void TestPushBack()
{
InitLinList(&first);
PushBack(&first, 1);
PushBack(&first, 2);
PushBack(&first, 3);
PushBack(&first, 4);
PrintLinList(first);
}
void TestPopFront()
{
InitLinList(&first);
PushBack(&first, 1);
PushBack(&first, 2);
PushBack(&first, 3);
PushBack(&first, 4);
PrintLinList(first);
PopFront(&first);
PrintLinList(first);
PopFront(&first);
PrintLinList(first);
PopFront(&first);
PrintLinList(first);
PopFront(&first);
PrintLinList(first);
}
void TestPopBack()
{
InitLinList(&first);
PushBack(&first, 1);
PushBack(&first, 2);
PushBack(&first, 3);
PushBack(&first, 4);
PrintLinList(first);
PopBack(&first);
PrintLinList(first);
PopBack(&first);
PrintLinList(first);
PopBack(&first);
PrintLinList(first);
PopBack(&first);
PrintLinList(first);
}
void TestFindLinList()
{
Node* ret = 0;
InitLinList(&first);
PushBack(&first, 1);
PushBack(&first, 2);
PushBack(&first, 3);
PushBack(&first, 4);
PrintLinList(first);
ret = FindLinList(&first, 1);
if (ret == NULL)
{
printf("数据不存在\n");
}
else
printf("%p\n", ret);
}
void TestInsert()
{
InitLinList(&first);
PushBack(&first, 1);
PushBack(&first, 2);
PushBack(&first, 3);
PushBack(&first, 4);
PrintLinList(first);
Node* p = FindLinList(&first, 3);
Insert(&first, p, 10);
PrintLinList(first);
}
void TestErase()
{
InitLinList(&first);
PushBack(&first, 1);
PushBack(&first, 2);
PushBack(&first, 3);
PushBack(&first, 4);
PrintLinList(first);
Node* p = FindLinList(&first, 3);
Erase(&first, p);
PrintLinList(first);
}
void TestRemove()
{
InitLinList(&first);
PushBack(&first, 1);
PushBack(&first, 2);
PushBack(&first, 1);
PushBack(&first, 3);
PushBack(&first, 1);
PrintLinList(first);
Remove(&first, 1);
PrintLinList(first);
}
void TestRemoveAll()
{
InitLinList(&first);
PushBack(&first, 1);
PushBack(&first, 2);
PushBack(&first, 1);
PushBack(&first, 3);
PushBack(&first, 1);
PrintLinList(first);
RemoveAll(&first, 1);
PrintLinList(first);
}
int main()
{
//一个程序一个程序的测试,测试过的程序注释
//TestPushFront();
//TestPushBack();
//TestPopFront();
//TestPopBack();
//TestFindLinList();
//TestInsert();
//TestErase();
//TestRemove();
TestRemoveAll();
return 0;
}