C语言线性表的链式存储(详解)

news2025/2/1 15:50:28

线性表的链式存储
线性表的顺序存储:用一块连续的内存空间

线性表的链式存储:不连续的内存空间

链表是由一系列的节点组成,每个节点包含两个域,一个是数据域,一个是指针域
链表的插入和删除原理
在这里插入图片描述单项链表框架的搭建
头文件
在这里插入图片描述具体的代码如下所示

#ifndef LINKLIST_H
#define LINKLIST_H
#include <stdio.h>
#include <stdlib.h>
// 链表节点
typedef struct LINKNODE {
	// 使用无类型的指针:该指针可以指向任何类型的数据
	void * data;
	struct LINKNODE* next;

}LinkNode;

// 链表结构体
typedef struct LINKLIST {
	LinkNode* head;
	int size;
	// 根据需要申请内存,没有容量的概念

}LinkList;

// 打印回调函数指针
typedef void(*PRINTLINKNODE)(void*);

// 初始化链表
LinkList* Init_LinkList();
// 在指定的位置插入
void Insert_LinkList(LinkList* list, int pos, void* data);
// 删除指定位置的值
void RemoveByPos_LinkList(LinkList* list, int pos);
// 获得链表的长度
void Size_LinkList(LinkList* list);
//查找链表
int Find_LinkList(LinkList* list,void * data);
// 打印链表节点
void Print_LinkList(LinkList* list, PRINTLINKNODE print);



// 返回第一个节点
void* Front_LinkList(LinkList* list);
// 释放链表内存
void FreeSpace_LinkList(LinkList* list);

#endif 

c语言文件
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <string.h>
#include "LinkList.h"

// 初始化链表
LinkList* Init_LinkList() {
	return NULL;
};
// 在指定的位置插入
void Insert_LinkList(LinkList* list, int pos, void* data) {

};
// 删除指定位置的值
void RemoveByPos_LinkList(LinkList* list, int pos) {

};
// 获得链表的长度
void Size_LinkList(LinkList* list) {
	//return 0;
};
//查找链表
int Find_LinkList(LinkList* list, void* data) {
	return 0;
};
// 打印链表节点
void Print_LinkList(LinkList* list, PRINTLINKNODE print) {

};

// 返回第一个节点
void* Front_LinkList(LinkList* list) {
	return 0;
};
// 释放链表内存
void FreeSpace_LinkList(LinkList* list) {

};

int main()
{

	printf("\n");
	system("pause");
	return 0;
}

数据结构中的基本概念

1:算法是为了解决问题二设计的

2:数据结构是算法需要处理问题的载体

3:数据结构与算法相辅相成

算法的表示方法

《只关注最高次项》

《如果最高次项的乘数不是1,就舍去》

《如果是常数》O(1)

malloc()容量,表示的是容器的概念

1:插入新元素,空间不足申请更大的内存空间

2:旧的空间的数据拷贝到新的空间

3:释放旧空间的内存

4:新元素插入到新的空间

链表的基本概念

1:线性表的顺序存储:用一块连续的内存空间

2:线性表的链式存储:不连续的内存空间

3:链表是由一系列的节点组成,每个节点包含两个域,一个是数据域,一个是指针域

单项链表的实现思路及代码
项目结构

在这里插入图片描述

#ifndef LINKLIST_H
#define LINKLIST_H
#include <stdio.h>
#include <stdlib.h>
// 链表节点
typedef struct LINKNODE {
	// 使用无类型的指针:该指针可以指向任何类型的数据
	void * data;
	struct LINKNODE* next;

}LinkNode;

// 链表结构体
typedef struct LINKLIST {
	LinkNode* head;
	int size;
	// 根据需要申请内存,没有容量的概念

}LinkList;

// 打印回调函数指针
typedef void(*PRINTLINKNODE)(void*);


// 初始化链表
LinkList* Init_LinkList();
// 在指定的位置插入
void Insert_LinkList(LinkList* list, int pos, void* data);
// 删除指定位置的值
void RemoveByPos_LinkList(LinkList* list, int pos);
// 获得链表的长度
int Size_LinkList(LinkList* list);
//查找链表
int Find_LinkList(LinkList* list,void * data);
// 打印链表节点
void Print_LinkList(LinkList* list, PRINTLINKNODE print);



// 返回第一个节点
void* Front_LinkList(LinkList* list);
// 释放链表内存
void FreeSpace_LinkList(LinkList* list);


#endif 

项目cpp文件代码LinkTableDirection.cpp
在这里插入图片描述LinkTableDirection.cpp

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <string.h>
#include "LinkList.h"

// 自定义的数据类型
typedef struct PERSON {
	char name[64];
	int age;
	int score;

}Person;

// 打印函数
void MyPrint(void* data) {
	Person* p = (Person*)data;
	printf("Name = %s Age = %d Score = %d\n", p->name, p->age, p->score);
};


// 初始化链表
LinkList* Init_LinkList() {
	// 分配内存空间
	LinkList* list = (LinkList*)malloc(sizeof(LinkList));
	list->size = 0; 
	// 头节点,是不保存数据信息的,方便实现链表的封装
	list->head = (LinkNode *)malloc(sizeof(LinkNode));
	list->head->data = NULL;
	list->head->next = NULL;
	return list;

};
// 在指定的位置插入
void Insert_LinkList(LinkList* list, int pos, void* data) {
	   // 判断参数是否符合我们的要求,也就是判断参数是否为空
	if (list == NULL) {
		return;
	}
	if (data == NULL) {
		return;
	}
	if (pos < 0 || pos > list->size) {
		pos = list->size;
	}
	// 创建新的节点
	LinkNode* newnode = (LinkNode*)malloc(sizeof(LinkNode));
	// 初始化,这个位置给出一个转换
	newnode->data = (void *)data;
	newnode->next = NULL;
	// 找节点,插入操作需要的是找到pos位置的前面一个节点,辅助指针变量
	LinkNode* pCurrent = list->head;
	for (int i = 0; i < pos; i++) {
		pCurrent = pCurrent->next;
	}
	//将新的节点放入链表
	newnode->next = pCurrent->next;
	pCurrent->next = newnode;
	list->size++;

};
// 删除指定位置的值
void RemoveByPos_LinkList(LinkList* list, int pos) {
	if (list == NULL) {
		return;
	}
	if (pos < 0 || pos >= list->size) {
		return;
	}
	// 查找删除节点的前一个节点
	LinkNode* pCurrent = list->head;
	for (int i = 0; i < pos; i++) {
		pCurrent = pCurrent ->next;

	}
	// 缓存删除的节点
	LinkNode* pDel = pCurrent->next;
	pCurrent->next = pDel->next;
	//释放删除节点的内存
	free(pDel);
	list->size--;



};
// 获得链表的长度
int Size_LinkList(LinkList* list) {
	return list->size;
	//return 0;
};
//查找链表
int Find_LinkList(LinkList* list, void* data) {
	if (list == NULL) {
		return -1;
	}
	if (data == NULL) {
		return -1;
	}
    // 遍历查找,使用辅助指针变量
	LinkNode* pCurrent = list->head->next;
	int i = 0;
	while (pCurrent != NULL) {
		if (pCurrent->data == data) {
			break;
		}
		i++;
		pCurrent = pCurrent->next;
	}
	return i;
	
};



// 返回第一个节点
void* Front_LinkList(LinkList* list) {
	// 返回的第一个节点就是头结点的下一个节点
	return list->head->next->data;
};

// 打印链表节点
void Print_LinkList(LinkList* list, PRINTLINKNODE print) {
	if (list == NULL) {
		return;
	}
	// 辅助指针变量
	LinkNode* pCurrent = list->head->next;
	while (pCurrent != NULL) {
		print(pCurrent->data);
		pCurrent = pCurrent->next;

	}
};

// 释放链表内存
void FreeSpace_LinkList(LinkList* list) {
	if (list == NULL) {
		return;
	}
	// 辅助指针变量
	LinkNode* pCurrent = list->head;
	while (pCurrent != NULL) {
	    // 缓存下一个节点
		LinkNode* pNext = pCurrent->next;
		pCurrent = pNext;
	}
	// 释放链表内存
	list->size = 0;
	free(list);
};


int main(void)
{
	void MyPrint(void* data);
	// 创建链表
	LinkList* list = Init_LinkList();
	// 创建数据
	Person p1 = { "aa",18,100 };
	Person p2 = { "hh",22,120 };
	Person p3 = { "zz",23,150 };
	Person p4 = { "qq",12,180 };
	Person p5 = { "ww",88,888 };

	// 将数据插入链表
	Insert_LinkList(list, 0, &p1);
	Insert_LinkList(list, 0, &p2);
	Insert_LinkList(list, 0, &p3);
	Insert_LinkList(list, 0, &p4);
	Insert_LinkList(list, 0, &p5);

	// 打印
	Print_LinkList(list, MyPrint);
	// 删除3号元素
	RemoveByPos_LinkList(list, 3);
	// 打印
	printf("-----------------------\n");
	Print_LinkList(list, MyPrint);

	// 返回第一个节点
	printf("-----------------------\n");
	Person* ret =  (Person *)Front_LinkList(list);
	printf("Name = %s Age = %d Score = %d\n", ret->name, ret->age, ret->score);

	// 销毁链表
	FreeSpace_LinkList(list);

	printf("\n");
	system("pause");
	return 0;
}

链表运行结果展示
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1271502.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习毕设项目 医学大数据分析 - 心血管疾病分析

# 1 前言 &#x1f6a9; 基于大数据的心血管疾病分析 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;4分 1 课题背景 本项目的任务是利用患者的检查结果预测心血管疾病(CVD)的存在与否。 2 数据…

老师怎么分配学生座位

学生座位分配是教育过程中的一个重要环节&#xff0c;对于学生的学习效果、课堂氛围以及师生互动都有一定的影响。那么&#xff0c;老师应该如何分配学生的座位呢&#xff1f; 了解每个学生的个性特点和学习习惯。不同的学生有不同的性格和特点&#xff0c;老师需要充分了解每个…

MAMP Pro v6.8.1(PHP/MySQL开发环境)

MAMP Pro是一款专为Mac用户设计的全功能本地服务器软件&#xff0c;可以将电脑变成一个完整的Web开发环境。无论个人开发者、网站管理员还是团队协作&#xff0c;MAMP Pro都提供了强大的工具和便捷的管理方式&#xff0c;能够更加高效地构建和测试网站。 MAMP Pro的基本功能包括…

Appium+Pytest实现app并发测试

前言 这个功能已经写完很长时间了&#xff0c;一直没有发出来&#xff0c;今天先把代码发出来吧&#xff0c;有一些代码是参考网上写的&#xff0c;具体的代码说明今天暂时先不发了&#xff0c;代码解释的太详细还得我花点时间^_^, 毕竟想让每个人都能看明白也不容易&#xff…

uniapp 使用web-view外接三方

来源 前阵子有个需求是需要在原有的项目上加入一个电子签名的功能&#xff0c;为了兼容性和复用性后面解决方法是将这个电子签名写在一个新的项目中&#xff0c;然后原有的项目使用web-view接入这个电子签名项目&#xff1b; 最近又有一个需求&#xff0c;是需要接入第三方的…

LeetCode(43)快乐数【哈希表】【简单】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 快乐数 1.题目 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1&#xff0c;也…

干销售找不到客户怎么办?

干销售找不到客户怎么办&#xff1f; 销售找不到客户&#xff1f;别担心&#xff0c;我们有解决方案&#xff01; 当你面临销售找不到客户的困境时&#xff0c;不要轻易放弃。相反&#xff0c;你可以采取一些策略来帮助你找到潜在的客户。以下是一些建议&#xff0c;它们将有…

什么是API? (应用程序编程接口)

我们经常听到 API 这个专业名称。那么什么是 API 呢&#xff1f; 定义 API&#xff08;Application Programming Interface&#xff0c;应用程序接口&#xff09;是一些预先定义的函数&#xff0c;或指软件系统不同组成部分衔接的约定。目的是提供应用程序与开发人员基于某软…

47、Flink 的指标报告介绍(graphite、influxdb、prometheus、statsd和datalog)及示例(jmx和slf4j示例)

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…

C/C++ Zlib库封装MyZip压缩类

Zlib是一个开源的数据压缩库&#xff0c;提供了一种通用的数据压缩和解压缩算法。它最初由Jean-Loup Gailly和Mark Adler开发&#xff0c;旨在成为一个高效、轻量级的压缩库&#xff0c;其被广泛应用于许多领域&#xff0c;包括网络通信、文件压缩、数据库系统等。其压缩算法是…

《如何戒掉坏习惯》精华摘抄

“劣质货币会驱逐优良货币。”这就是格雷沙姆法则&#xff08;劣币驱逐良币 法则&#xff09;。它是指一旦对劣质货币&#xff08;假币&#xff09;的流通放任不管&#xff0c;人们就不会 去使用优良货币&#xff08;真正的货币&#xff09;&#xff0c;从而导致优良货币从市场…

深入探索Maven:优雅构建Java项目的新方式(二)

Meven高级 1&#xff0c;属性1.1 属性1.1.1 问题分析1.1.2 解决步骤步骤1:父工程中定义属性步骤2:修改依赖的version 1.2 配置文件加载属性步骤1:父工程定义属性步骤2:jdbc.properties文件中引用属性步骤3:设置maven过滤文件范围步骤4:测试是否生效 1.3 版本管理 2&#xff0c;…

todesk连接ubuntu显示当前系统并无桌面环境,或无显示器,无法显示远程桌面,您需要自行安装X11桌面环境,或者使用终端文件功能

ToDesk远程遇到的问题如上图&#xff0c;换向日葵直接黑屏&#xff1b; 问题原因 截止发文时间&#xff0c;Todesk只支持X11协议&#xff0c;没有适配最新的Wayland协议&#xff0c;所以我们需要把窗口系统调整为X11才可以。 解决方法 修改配置文件&#xff0c;关闭wayland su…

Hadoop入门学习笔记

视频课程地址&#xff1a;https://www.bilibili.com/video/BV1WY4y197g7 课程资料链接&#xff1a;https://pan.baidu.com/s/15KpnWeKpvExpKmOC8xjmtQ?pwd5ay8 这里写目录标题 一、VMware准备Linux虚拟机1.1. VMware安装Linux虚拟机1.1.1. 修改虚拟机子网IP和网关1.1.2. 安装…

AI PC专题:AI PC深入变革PC产业

今天分享的是AI系列深度研究报告&#xff1a;《AI PC专题&#xff1a;AI PC深入变革PC产业》。 &#xff08;报告出品方&#xff1a;西南证券研究发展中心&#xff09; 报告共计&#xff1a;30页 AI PC将深入变革PC产业  从出货量看&#xff0c;PC整体呈现周期性的特征。2…

智慧灯杆网关:引领城市智慧照明的未来

智慧灯杆网关&#xff0c;作为城市智慧照明系统的核心组件&#xff0c;正逐渐成为各大城市发展的关键所在。它的出现使得城市照明管理更加智能、高效&#xff0c;为未来城市的可持续发展奠定了坚实的基础。 智慧灯杆网关是一种集网络通信、数据处理、远程控制等功能于一体的设备…

系统部署安装-Centos7-Cassandra

文章目录 介绍安装在线下载安装启动普通启动注册服务 介绍 Apache Cassandra是一个高度可扩展的高性能分布式数据库&#xff0c;旨在处理许多商用服务器上的大量数据&#xff0c;提供高可用性而没有单点故障。 安装 在线下载 &#xff08;1&#xff09;使用weget下载最新的…

火锅店管理系统扫码点餐小程序作用如何

火锅店在餐饮行业中占据了很高地位&#xff0c;受众非常广&#xff0c;当然火热的赛道自然少不了众多品牌竞争&#xff0c;由于火锅店有一定成本支出&#xff0c;所以商家更希望能加大生意营收&#xff0c;而强到店属性下&#xff0c;如何将客户饮料进店和赋能客户消费就变得很…

天眼销:精准的企业名录

企业名录的重要性&#xff0c;对于销售而言都是极其重要的。本期为家人们分享如何正确挑选出优质的企业名录渠道&#xff0c;避免走一些弯弯坑坑。 为了有效利用企业名录进行客户开发&#xff0c;您需要关注信息的准确性、可提供的资源数量以及信息的时效性。能否根据您的需求…

封装进度条onUploadProgress+axios取消请求的上传组件

目录 定时模拟进度条 方法 A.axios B.xhr 取消请求 完整代码 A.自定义上传组件 B.二次封装组件 情况 增加cancelToken不生效&#xff0c;刷新页面 进度条太快->设置浏览器网速 定时模拟进度条 startUpload() {if (!this.file) return;const totalSize this.fil…