//LinkList.h
#pragma once
#include <stdio.h>
#include <stddef.h>
#include <Windows.h>
#include <stdlib.h>
typedef char LinkType;
typedef struct LinkNode {
LinkType data;
struct LinkNode* next;
} LinkNode;
void LinkListInit(LinkNode** head);//初始化链表
LinkNode* LinkListPushBack(LinkNode** head, LinkType value);//尾插一个元素到链表中
void LinkListPopBack(LinkNode** head);//尾删一个元素
void LinkListPushFront(LinkNode** head, LinkType value);//头插一个元素
void LinkListPopFront(LinkNode** head);//头删一个元素
/**
* @brief 查找元素在链表中的位置
*
* @param head
* @param to_find 要查找的值
*
* @return 这个值对应的节点的地址
*/
LinkNode* LinkListFind(LinkNode* head, LinkType to_find);
void LinkListInsert(LinkNode** head, LinkNode* pos, LinkType value);//在pos之前插入元素
void LinkListInsertAfter(LinkNode** head, LinkNode* pos, LinkType value);//在pos之后插入元素
void LinkListErase(LinkNode** head, LinkNode* pos);//删除指定位置的元素
void LinkListErase2(LinkNode** head, LinkNode* pos);//删除指定位置的元素 O(1)
void LinkListRemove(LinkNode** head, LinkType to_delete);//删除指定值的元素
void LinkListRemoveAll(LinkNode** head, LinkType value);//指定值的所有元素都删掉.
/**
* @brief 判定链表为空
*
* @return 链表为空, 返回1, 否则返回0
*/
int LinkListEmpty(LinkNode* head);
size_t LinkListSize(LinkNode* head);//求链表的元素个数
//LinkList.c
#include "LinkList.h"
//初始化链表
void LinkListInit(LinkNode** head)
{
if (head == NULL)
{
//非法操作
return;
}
if (*head == NULL)
{
//空链表
return;
}
*head = NULL;
return;
}
LinkNode *LinkListCreateNode(LinkType value)
{
LinkNode * new_node = (LinkNode *)malloc(sizeof(LinkNode));
new_node->data = value;
new_node->next = NULL;
return new_node;
}
void LinkListDestoryNode(LinkNode *to_delete)
{
free(to_delete);
}
//尾插一个元素到链表中
LinkNode* LinkListPushBack(LinkNode** head, LinkType value)
{
if (head == NULL)
{
//非法操作
return NULL;
}
if (*head == NULL)
{
//空链表
*head = LinkListCreateNode(value);
return *head;
}
LinkNode *cur = *head;
while (cur->next != NULL)
{
cur = cur->next;
}
cur->next = LinkListCreateNode(value);
return cur->next;
}
//尾删一个元素
void LinkListPopBack(LinkNode** head)
{
if (head == NULL || *head == NULL)
{
return;
}
if ((*head)->next == NULL)
{
//只有一个节点
LinkNode *to_delete = *head;
*head = NULL;
LinkListDestoryNode(to_delete);
return;
}
LinkNode *cur = *head;
while (cur->next != NULL)
{
if (cur->next->next == NULL)
{
LinkNode *to_delete = cur->next;
cur->next = to_delete->next;
LinkListDestoryNode(to_delete);
return;
}
cur = cur->next;
}
return;
}
//头插一个元素
void LinkListPushFront(LinkNode** head, LinkType value)
{
if (head == NULL)
{
return;
}
if (*head == NULL)
{
LinkListPushBack(head, value);
return;
}
LinkNode *cur = *head;
cur = LinkListCreateNode(value);
cur->next = *head;
*head = cur;
return;
}
//头删一个元素
void LinkListPopFront(LinkNode** head)
{
if (head == NULL || *head == NULL)
{
return;
}
if ((*head)->next == NULL)
{
//只有一个节点
LinkListPopBack(head);
return;
}
LinkNode *cur = *head;
*head = cur->next;
LinkListDestoryNode(cur);
}
LinkNode* LinkListFind(LinkNode* head, LinkType to_find)
{
if (head == NULL)
{
return NULL;
}
LinkNode *cur = head;
if (cur->data == to_find)
{
//只有一个节点的时候
return cur;
}
while (cur->next != NULL)
{
if (cur->data == to_find)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
//在pos之前插入元素
void LinkListInsert(LinkNode** head, LinkNode* pos, LinkType value)
{
if (head == NULL || *head == NULL)
{
return;
}
if (pos == NULL)
{//如果pos==NULL 就尾插一个元素
LinkListPushBack(head, value);
return;
}
if ((*head)->next == NULL)
{//如果只有一个元素并且第一个元素为pos的值,就头插一个元素
if (pos == *head)
{
LinkListPushFront(head, value);
return;
}
return;
}
LinkNode* cur = *head;
while (cur->next != NULL)
{
if (cur->next == pos)
{
LinkNode * new_node = LinkListCreateNode(value);
new_node->next = cur->next;
cur->next = new_node;
return;
}
cur = cur->next;
}
}
//在pos之后插入元素
void LinkListInsertAfter(LinkNode** head, LinkNode* pos, LinkType value)
{
if (head == NULL || *head == NULL || pos == NULL)
{
return;
}
LinkNode* cur = *head;
while (cur != NULL)
{
if (cur == pos)
{
LinkNode* new_node = LinkListCreateNode(value);
new_node->next = cur->next;
cur->next = new_node;
return;
}
cur = cur->next;
}
return;
}
//删除指定位置的元素
void LinkListErase(LinkNode** head, LinkNode* pos)
{
if (head == NULL || *head == NULL)
{
return;
}
LinkNode *cur = *head;
if (pos == *head)
{
LinkListPopFront(head);
return;
}
while (cur->next != NULL)
{
if (cur->next == pos)
{
LinkNode* to_delete = cur->next;
cur->next = to_delete->next;
LinkListDestoryNode(to_delete);
}
cur = cur->next;
}
return;
}
//删除指定位置的元素 O(1)
void LinkListErase2(LinkNode** head, LinkNode* pos)
{
if (head == NULL || *head == NULL || pos == NULL)
{//非法操作 空链表 空指针
return;
}
LinkNode *cur = *head;
if (cur->next == NULL)
{//如果链表只有一个元素
if (cur = pos)
LinkListPopBack(head);
return;
}
if (pos->next == NULL)
{//如果pos是最后一个元素
if (cur = pos)
LinkListPopBack(head);
return;
}
pos->data = pos->next->data;
LinkNode *to_delete = pos->next;
pos->next = pos->next->next;
LinkListDestoryNode(to_delete);
}
//删除指定值的元素
void LinkListRemove(LinkNode** head, LinkType to_delete)
{
if (head == NULL || *head == NULL)
{
return;
}
LinkNode* cur = *head;
if (cur->next == NULL)
{//只有一个节点
if (cur->data == to_delete)
{
*head = NULL;
LinkListDestoryNode(cur);
}
return;
}
while (cur->next != NULL)
{
if (cur->next->data == to_delete)
{//找到要删除的节点
LinkNode* deletenode = cur->next;
cur->next = deletenode->next;
LinkListDestoryNode(deletenode);
}
cur = cur->next;
}
//没有找到节点
return;
}
//指定值的所有元素都删掉.
void LinkListRemoveAll(LinkNode** head, LinkType value)
{
if (head == NULL || *head == NULL)
{
return;
}
LinkNode *cur = *head;
if (cur->next == NULL)
{
if (cur->data == value)
LinkListPopBack(head);
return;
}
while (cur->next != NULL)
{
if (cur->data == value)
LinkListErase2(head, cur);
else
cur = cur->next;
}
return;
}
//判断链表是否为空
int LinkListEmpty(LinkNode* head)
{
if (head == NULL)
return 1;
return 0;
}
//求链表的元素个数
size_t LinkListSize(LinkNode* head)
{
if (head == NULL)
{
return 0;
}
size_t count = 1;
LinkNode *cur = head;
while (cur->next != NULL)
{
cur = cur->next;
count++;
}
return count;
}
//test.c
#include "LinkList.h"
#define FUN_HEADER printf("\n==================%s==================\n",__FUNCTION__);
void LinkListPrintChar(LinkNode *head,char *ch)
{
printf("[%s] ", ch);
LinkNode *cur = head;
for (; cur != NULL; cur = cur->next)
{
printf("[%c:%p] -> ", cur->data, cur);
}
printf("[NULL]\n");
}
void TestInit()
{
FUN_HEADER;
LinkNode *head;
LinkListInit(&head);
LinkListPrintChar(head, "初始化链表");
}
void TestPushBack()
{
FUN_HEADER;
LinkNode *head;
LinkListInit(&head);
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'b');
LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkListPushBack(&head, 'e');
LinkListPrintChar(head, "尾插五个元素");
}
void TestPopBack()
{
FUN_HEADER;
LinkNode *head;
LinkListInit(&head);
LinkListPopBack(&head);
LinkListPrintChar(head, "对空链表进行尾删");
LinkListPushBack(&head, 'a');
LinkListPopBack(&head);
LinkListPrintChar(head, "对只有一个节点的链表进行尾删");
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'b');
LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkListPopBack(&head);
LinkListPrintChar(head,"对链表进行尾删");
}
void TsetPushFront()
{
FUN_HEADER;
LinkNode *head;
LinkListInit(&head);
LinkListPushFront(&head, 'a');
LinkListPushFront(&head, 'b');
LinkListPushFront(&head, 'c');
LinkListPushFront(&head, 'd');
LinkListPrintChar(head, "头插四个元素");
}
void TestPopFront()
{
FUN_HEADER;
LinkNode *head;
LinkListInit(&head);
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'b');
LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkListPrintChar(head, "尾插四个元素");
LinkListPopFront(&head);
LinkListPrintChar(head, "头删一个元素");
LinkListPopFront(&head);
LinkListPopFront(&head);
LinkListPrintChar(head, "再头删两个元素");
}
void TestLinkListFind()
{
FUN_HEADER;
LinkNode *head;
LinkListInit(&head);
LinkListFind(head, 'a');
LinkListPrintChar(head, "链表为空时查找");
LinkListPushBack(&head, 'a');
LinkNode * pos_b = LinkListPushBack(&head, 'b');
LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkNode * pos = LinkListFind(head, 'b');
printf("pos_b expect %p,actually %p\n", pos_b, pos);
pos = LinkListFind(head, 'x');
printf("pos_x expect NULL,actually %p\n", pos);
}
void TestInsert()
{
FUN_HEADER;
LinkNode* head;
LinkListInit(&head);
LinkListPushBack(&head, 'a');
LinkListPrintChar(head, "尾插一个元素");
LinkListInsert(&head, head, 'x');
LinkListPrintChar(head, "在a前插入一个 x");
LinkListPushBack(&head, 'b');
LinkListPushBack(&head, 'c');
LinkNode * pos_d = LinkListPushBack(&head, 'd');
LinkListPrintChar(head, "尾再插三个元素");
LinkListInsert(&head, pos_d, 'y');
LinkListPrintChar(head, "在d前插入一个 y");
}
void TestInsertAfter()
{
FUN_HEADER;
LinkNode *head;
LinkListInit(&head);
LinkListPushBack(&head, 'a');
LinkListInsertAfter(&head, head, 'y');
LinkListPrintChar(head, "在a之后插入 y");
LinkListPushBack(&head, 'b');
LinkNode * pos_c = LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkListInsertAfter(&head, pos_c, 'x');
LinkListPrintChar(head, "在c之后插入 x");
}
void TestErase()
{
FUN_HEADER;
LinkNode * head;
LinkListInit(&head);
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'b');
LinkNode* pos_c = LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkListPrintChar(head, "尾插四个元素");
LinkListErase(&head,head);
LinkListPrintChar(head, "删除头结点");
LinkListErase(&head, pos_c);
LinkListPrintChar(head, "删除c节点");
}
void TetsErase2()
{
FUN_HEADER;
LinkNode * head;
LinkListInit(&head);
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'b');
LinkNode* pos_c = LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkListPrintChar(head, "尾插四个元素");
LinkListErase2(&head, head);
LinkListPrintChar(head, "删除头结点");
LinkListErase2(&head, pos_c);
LinkListPrintChar(head, "删除c节点");
LinkListErase2(&head, pos_c);
LinkListPrintChar(head, "删除最后一个节点d");
}
void TestRemove()
{
FUN_HEADER;
LinkNode* head;
LinkListInit(&head);
LinkListPushBack(&head, 'a');
LinkListPrintChar(head, "尾插一个元素");
LinkListRemove(&head, 'x');
LinkListPrintChar(head, "删除不存在的元素x");
LinkListRemove(&head, 'a');
LinkListPrintChar(head, "链表只有一个元素a,删除a");
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'b');
LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkListPrintChar(head, "尾插五个元素");
LinkListRemove(&head, 'x');
LinkListPrintChar(head, "删除不存在的元素x");
LinkListRemove(&head, 'c');
LinkListPrintChar(head, "删除存在的元素c,如果重复,只删除第一个");
}
void TestRemoveAll()
{
FUN_HEADER;
LinkNode * head;
LinkListInit(&head);
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'b');
LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkListPrintChar(head, "尾插六个元素");
LinkListRemoveAll(&head, 'c');
LinkListPrintChar(head, "删除所有的c");
}
void TestEmpty()
{
FUN_HEADER;
LinkNode * head;
LinkListInit(&head);
int ret = LinkListEmpty(head);
printf("expect 1,actully %d\n", ret);
LinkListPushBack(&head, 'a');
ret = LinkListEmpty(head);
printf("expect 0,actully %d\n", ret);
}
void TestLinkSize()
{
FUN_HEADER;
LinkNode * head;
LinkListInit(&head);
size_t size = LinkListSize(head);
printf("expect 0,actully %lu\n", size);
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'a');
size = LinkListSize(head);
printf("expect 5,actully %lu\n", size);
}
int main()
{
TestInit();
TestPushBack();
TestPopBack();
TsetPushFront();
TestPopFront();
TestLinkListFind();
TestInsert();
TestInsertAfter();
TestErase();
TetsErase2();
TestRemove();
TestRemoveAll();
TestEmpty();
TestLinkSize();
system("pause");
return 0;
}