以下为单链表(不带头节点,不带环)的C语言实现代码
注:更多功能的实现请查看 单链表(进击版)
实现功能(基础版)
//初始化链表头节点
//链表尾插
//链表头插
//链表尾删
//链表头删
//查找元素在链表中的地址
//查找元素在链表中的下标
头文件代码link.h
#pragma once //防止头文件重复包含
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Datatype char
typedef struct LinkNode //定义结构体
{
Datatype data; //存储内容
struct LinkNode* next; //指向下一个节点
}LinkNode;
//创建节点
LinkNode* LinklistCreat(void);
//删除节点
void LinklistDestroy(LinkNode* head);
//初始化链表头节点
void LinklistInit(LinkNode** phead); //使用LinkNode** 类型因为链表可能需要修改头指针指向
//链表尾插
void LinklistPushback(LinkNode** phead, Datatype value);
//链表头插
void LinklistPushfront(LinkNode** phead, Datatype value);
//链表尾删
void LinklistPopback(LinkNode** phead);
//链表头删
void LinklistPopfront(LinkNode** phead);
//查找元素在链表中的地址
LinkNode* LinklistFind(LinkNode* head, Datatype to_find);
//查找元素在链表中的下标
size_t LinklistFind1(LinkNode* head, Datatype to_find);
函数实现代码link.c
#include "link.h"
//创建节点
LinkNode* LinklistCreat(void)
{
LinkNode* new = malloc(sizeof(LinkNode));
return new;
}
//删除节点
void LinklistDestroy(LinkNode* head)
{
if (head == NULL)
{
printf("空指针");
return;
}
free(head);
}
//初始化链表头节点
void LinklistInit(LinkNode** phead)
{
if (phead == NULL)
{
printf("空指针");
return;
}
*phead = NULL;
}
//链表尾插
void LinklistPushback(LinkNode** phead, Datatype value)
{
if (phead == NULL)
{
printf("非法输入");
return;
}
//空链表尾插
if (*phead == NULL)
{
*phead = LinklistCreat(); //创建节点
(*phead)->data = value; //节点赋值
(*phead)->next = NULL; //插入空链表即新节点指向空
return;
}
//常规尾插
LinkNode* new = LinklistCreat(); //创建新节点
LinkNode* cur = *phead;
new->data = value;
new->next = NULL;
while (cur->next!= NULL) //使cur指向最后一个节点
{
cur = cur->next;
}
cur->next = new; //最后节点的下一个节点即指向新节点
return;
}
//链表头插
void LinklistPushfront(LinkNode** phead, Datatype value)
{
if (phead == NULL)
{
printf("非法输入");
return;
}
LinkNode* new = LinklistCreat(); //创建节点
new->data = value;
LinkNode* cur = *phead; //cur指向头指针
*phead = new;
new->next = cur; //新节点指向,指向头节点的指针
}
//链表尾删
void LinklistPopback(LinkNode** phead)
{
if (phead == NULL)
{
printf("非法输入");
return;
}
if (*phead == NULL)
{
printf("空链表");
return;
}
//只有一个元素
if ((*phead)->next == NULL)
{
LinkNode* tmp = *phead; //保存头指针指向
*phead = NULL; //置空
LinklistDestroy(tmp); //销毁节点
return;
}
//两个及以上元素
LinkNode* cur = *phead;
LinkNode* pre = NULL;
while (cur->next != NULL) //使cur指向最后一个节点
{ //使pre指向倒数第二个节点
pre = cur;
cur = cur->next;
}
pre->next = NULL; //尾删,即倒数第二个节点指向空
LinklistDestroy(cur); //销毁最后一个节点
}
//链表头删
void LinklistPopfront(LinkNode** phead)
{
if (phead == NULL)
{
printf("非法输入");
return;
}
if (*phead == NULL)
{
printf("空链表");
return;
}
//常规头删
LinkNode* cur = *phead; //创建指向头节点的指针
*phead = (*phead)->next; //头节点指向下一个节点
LinklistDestroy(cur); //销毁指向头节点的指针
return;
}
//查找元素在链表中的地址
LinkNode* LinklistFind(LinkNode* head, Datatype to_find)
{
if (head == NULL)
{
printf("空链表");
return NULL ;
}
LinkNode *cur = head;
while (cur != NULL)
{
if (cur->data == to_find)
{
return cur; //找到则返回结构体地址
}
cur = cur->next; //遍历要查找的元素
}
printf("没有找到\n");
return NULL;
}
//查找元素在链表中的下标
size_t LinklistFind1(LinkNode* head, Datatype to_find)
{
if (head == NULL)
{
printf("空链表");
return ;
}
size_t count = 0;
LinkNode *cur = head;
while (cur != NULL)
{
count++; //定义计数器
if (cur->data == to_find)
{
return count;
}
cur = cur->next;
}
printf("没有找到\n");
return ;
}
测试代码test.c
#include "link.h"
#include<stdio.h>
#include<stdlib.h>
/************************************************************************
* tset
***********************************************************************/
//定义一个宏来打印调试函数提示信息
#define FUNCTION() printf("**************** %s ************\n" , __FUNCTION__)
void printChar(LinkNode* head ,const char *msg)
{
if (head == NULL)
{
printf("空指针");
return;
}
printf("%s\n", msg);
for (; head != NULL; head = head->next)
{
printf("%c\n", head->data);
}
printf("\n");
return;
}
void TestPushback()
{
FUNCTION();
LinkNode* head;
LinklistInit(&head);
LinklistPushback(&head, 'a');
LinklistPushback(&head, 'b');
LinklistPushback(&head, 'c');
LinklistPushback(&head, 'd');
printChar(head, "尾插a,b,c,d");
}
void TestPushfront()
{
FUNCTION();
LinkNode* head;
LinklistInit(&head);
LinklistPushfront(&head, 'a');
LinklistPushfront(&head, 'b');
LinklistPushfront(&head, 'c');
LinklistPushfront(&head, 'd');
printChar(head, "头插a,b,c,d");
}
void TestPopback()
{
FUNCTION();
LinkNode* head;
LinklistInit(&head);
LinklistPushback(&head, 'a');
LinklistPushback(&head, 'b');
LinklistPushback(&head, 'c');
LinklistPushback(&head, 'd');
printChar(head, "尾插a,b,c,d");
LinklistPopback(&head);
LinklistPopback(&head);
printChar(head, "尾删两节点");
}
void TestPopfront()
{
FUNCTION();
LinkNode* head;
LinklistInit(&head);
LinklistPushback(&head, 'a');
LinklistPushback(&head, 'b');
LinklistPushback(&head, 'c');
LinklistPushback(&head, 'd');
printChar(head, "尾插a,b,c,d");
LinklistPopfront(&head);
LinklistPopfront(&head);
printChar(head, "头删两节点");
}
void TestFind()
{
FUNCTION();
LinkNode* head;
LinklistInit(&head);
LinklistPushback(&head, 'a');
LinklistPushback(&head, 'b');
LinklistPushback(&head, 'c');
LinklistPushback(&head, 'd');
LinkNode* ret = LinklistFind(head, 'b');
printf("a的存储位置%p\n", ret->data);
}
void TestFind1()
{
FUNCTION();
LinkNode* head;
LinklistInit(&head);
LinklistPushback(&head, 'a');
LinklistPushback(&head, 'b');
LinklistPushback(&head, 'c');
LinklistPushback(&head, 'd');
LinklistFind1(head, 'a');
size_t ret = LinklistFind1(head, 'a');
printf("a的下标 %lu \n", ret);
}
void TestInsert()
{
FUNCTION();
LinkNode* head;
LinklistInit(&head);
LinklistPushback(&head, 'a');
LinklistPushback(&head, 'b');
LinklistPushback(&head, 'c');
LinklistPushback(&head, 'd');
printChar(head, "尾插a,b,c,d");
LinklistInsert(&head, head ,'x');
printChar(head, "a之前插入x");
}
void TestInsertAfter()
{
FUNCTION();
LinkNode* head;
LinklistInit(&head);
LinklistPushback(&head, 'a');
LinklistPushback(&head, 'b');
LinklistPushback(&head, 'c');
LinklistPushback(&head, 'd');
printChar(head, "尾插a,b,c,d");
LinklistInsertAfter(&head, head->next, 'x');
printChar(head, "b之后插入x");
}
void TestErase()
{
FUNCTION();
LinkNode* head;
LinklistInit(&head);
LinklistPushback(&head, 'a');
LinklistPushback(&head, 'b');
LinklistPushback(&head, 'c');
LinklistPushback(&head, 'd');
printChar(head, "尾插a,b,c,d");
LinklistErase(&head, head);
printChar(head, "删除头节点的元素a");
}
void TestRemove()
{
FUNCTION();
LinkNode* head;
LinklistInit(&head);
LinklistPushback(&head, 'a');
LinklistPushback(&head, 'b');
LinklistPushback(&head, 'c');
LinklistPushback(&head, 'd');
printChar(head, "尾插a,b,c,d");
LinklistRemove(&head, 'a');
printChar(head, "删除指定元素a");
}
void TestSize()
{
FUNCTION();
LinkNode* head;
LinklistInit(&head);
LinklistPushback(&head, 'a');
LinklistPushback(&head, 'b');
LinklistPushback(&head, 'c');
LinklistPushback(&head, 'd');
LinklistSize(head);
size_t count = LinklistSize(head);
printf("count=%lu\n", count);
printChar(head, "求链表元素的个数");
}
void TestEmpty()
{
FUNCTION();
LinkNode* head;
LinklistInit(&head);
LinklistPushback(&head, 'a');
LinklistPushback(&head, 'b');
LinklistPushback(&head, 'c');
LinklistPushback(&head, 'd');
LinklistPopback(&head);
LinklistPopback(&head);
LinklistEmpty(head);
int i = LinklistEmpty(head);
printf("i=%d\n", i);
printChar(head, "判断链表是否为空");
}
int main()
{
TestPushback();
TestPushfront();
TestPopback();
TestPopfront();
TestFind();
TestFind1();
return 0;
}