单链表原码分享(C语言)

149 阅读3分钟

单链表原码分享(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(文件名就叫做链表)