单链表原码分享(C语言)
1、头文件
List.h
#pragma once
/*
* 1 实现一个表的数据结构,可以进行插入、查询、删除、判空、获取大小等操作
* 2 底层使用链表存储
*/
#include <stdio.h>
#include <stdlib.h> //malloc
#include <stdbool.h> //boll类型
//函数原型声明
struct Node* CreateHeaderNode();
void InsertFirst(struct Node* header, int x);
void InsertLast(struct Node* header, int x);
void Insert(struct Node* header, int x, int position);
struct Node* Find(struct Node* header, int x);
struct Node* FindKth(struct Node* header, int position);
void Delete(struct Node* header, int x);
bool IsEmpty(struct Node* header);
int Size(struct Node* header);
void PrintList(struct Node* header);
struct Node
{
int element; //节点中的值
struct Node* next; //执行下一个节点的指针
};
2、函数实现
2.1 CreateHeaderNode.c(创建表头)
#include "List.h"
//创建表头
struct Node* CreateHeaderNode()
{
struct Node* p = malloc(sizeof(struct Node));
if (p == NULL) {
printf("内存空间内存不足,创建表头失败");
exit(1);
}
p->next = NULL;
return p;
}
2.2 InsertFirst.c(头插)
#include "List.h"
//从表头插入
void InsertFirst(struct Node* header, int x)
{
struct Node* tmp = malloc(sizeof(struct Node));
if (tmp == NULL) {
printf("内存空间不足,插入失败");
exit(1);
}
tmp->element = x;
tmp->next = header->next;
header->next = tmp;
}
2.3 InsertLast.c(尾插)
#include "List.h"
void InsertLast(struct Node* header, int x)
{
struct Node* tmp;
struct Node* p = malloc(sizeof(struct Node));
if (p == NULL) {
printf("内存空间不足,尾插失败");
exit(1);
}
p->element = x;
p->next = NULL;
tmp = header;
while (tmp->next != NULL) {
tmp = tmp->next;
}
tmp->next = p;
}
2.4 Insert.c(插入)
#include "List.h"
void Insert(struct Node* header, int x, int position)
{
struct Node* privious = header;
struct Node* p = header->next;
struct Node* insert = malloc(sizeof(struct Node));
int count = 1;
while (p != NULL) {
if (count == position) {
break;
}
else {
privious = p;
p = p->next;
count++;
}
}
if (NULL == p) {
printf("你输入的位置过大,请输入一个合适的位置插入数据");
return;
}
insert->element = x;
insert->next = p;
privious->next = insert;
}
2.5 Find.c(按照值查找)
#include "List.h"
struct Node* Find(struct Node* header, int x)
{
struct Node* tmp;
tmp = header->next;
while (tmp != NULL && tmp->element != x) {
tmp = tmp->next;
}
return tmp;
}
2.6 FindKth(按照位置查找)
#include "List.h"
struct Node* FindKth(struct Node* header, int position)
{
int count = 1;
struct Node* p = header->next;
if (position <= 0) {
printf("请输入一个大于等于1的位置");
}
while (p != NULL) {
if (count == position) {
return p;
}
p = p->next;
count++;
}
return NULL;
}
2.7 Delete.c(删除)
#include "List.h"
void Delete(struct Node* header, int x)
{
struct Node* privious = header;
struct Node* p = header->next;
while (p != NULL) {
if (p->element == x) {
privious->next = p->next;
free(p);
return;
}
privious = p;
p = p->next;
}
printf("未能找到你想删除的数");
return;
}
2.8 IsEmpty.c(判断是否为空)
#include "List.h"
//判断链表是否为空
bool IsEmpty(struct Node* header)
{
return header->next == NULL;
}
2.9 Size.c(计算单链表的大小)
#include "List.h"
int Size(struct Node* header)
{
int count = 0;
struct Node* p = header->next;
while (p != NULL) {
count++;
p = p->next;
}
return count;
}
2.10 PrintList.c(打印单链表)
#include "List.h"
void PrintList(struct Node* header)
{
struct Node* p;
p = header->next;
printf("该链表各节点的值为:");
while (p != NULL) {
printf("%d ", p->element);
p = p->next;
}
printf("\n");
}
3、主函数
main.c
#include "List.h"
int main()
{
struct Node* node;
struct Node* header;
//创建表头(哑节点)
header = CreateHeaderNode();
//判断表是否为空
printf("List isEmpty:%d\n", IsEmpty(header));
printf("--------------------------\n");
//从表头插入
InsertFirst(header, 1);
InsertFirst(header, 2);
PrintList(header);
printf("--------------------------\n");
//从尾部插入
InsertLast(header, 3);
InsertLast(header, 4);
PrintList(header);
printf("--------------------------\n");
printf("List isEmpty:%d\n", IsEmpty(header));
printf("--------------------------\n");
//查找节点值为3的节点
node = Find(header, 3);
if (node == NULL) {
printf("not find...\n");
}
else {
printf("find node element:%d\n", node->element);
}
printf("--------------------------\n");
//查找第4个节点的值
node = FindKth(header, 1);
if (node == NULL) {
printf("not find...\n");
}
else {
printf("find node position:%d\n", node->element);
}
printf("--------------------------\n");
//删除值为3的节点
Delete(header, 3);
PrintList(header);
printf("--------------------------\n");
//打印表中节点个数,即表示表的大小
printf("List szie:%d\n", Size(header));
printf("--------------------------\n");
//在位置为2处插入5
Insert(header, 5, 3);
PrintList(header);
return 0;
}
4、写在后面
以上展示了单链表中常见的几种操作,如有纰漏、补充,欢迎私信、评论区友好指正、讨论。
为方便大家学习,原码已放在GitHub,欢迎下载link(文件名就叫做链表)