顺序表的实现--C语言泛型编程

Nacos 从困惑到蒙圈(9)Nacos 适配 达梦数据库【最新版】 介绍Nacos适配达梦数据库的详细步骤,包括对最新版本的支持改造。 阅读详情
一:顺序表代码实现
#ifndef _SEQ_LIST_H
#define _SEQ_LIST_H

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

#define ElemType float           //以float类型测试算法通用性,而不是以惯用的int
#define INIT_SIZE 10             //顺序表默认初始化大小
#define LIST_INCREMENT 5         //顺序表容量增量,容量不够使用malloc申请

#define list_full(list) ((list)->size >= (list)->capacity ? 1 : 0)       //顺序表判满
#define list_empty(list) ((list)->size == 0 ? 1 : 0)                     //判空

typedef ElemType value_type;                      //元素类型
typedef value_type* value_ptr;                    //元素指针类型
typedef enum {false, true}bool;                   //为C语言增加bool量
typedef enum {POSITION, VALUE}DELETE_MODE;        //删除元素模式选择,分别为按位置删除和按值删除

typedef struct sequelize_list{
	ElemType *base;                  //顺序表基址
	int size;                        //顺序表元素大小
	int capacity;                    //顺序表容量
} seq_list, *list_ptr;

void init_list(list_ptr lp)          //初始化
{
	assert(lp != NULL);

	lp->base = (value_ptr)malloc(sizeof(value_type)*INIT_SIZE);  //free
	assert(lp->base != NULL);

	memset(lp->base, 0, sizeof(value_type)*INIT_SIZE);

	lp->size = 0;
	lp->capacity = INIT_SIZE;
}

bool insert_elem(list_ptr lp, const int pos, const value_type elem)                //插入元素
{
	assert(lp != NULL && pos >= 1 && pos <= lp->size+1);

	if(list_full(lp)){                  //如果表满,追加申请空间
		value_ptr new_base = (value_ptr)realloc(lp->base, 
								sizeof(value_type)*(lp->capacity+LIST_INCREMENT));//此处注意realloc用法,用新地址接收是为了防止realloc失败,原地址有效内容被释放
		assert(new_base != NULL);      //并且realloc填写的申请空间大小必须是之前的大小+增量的大小,而不是只写增量,否则如果原地址内存不够,在新地址申请增量大小的空间,将之前的内容挪至新空间,内存溢出,将发生段错误
		
		lp->base = new_base;           //再赋回给原地址
		lp->base[lp->capacity] = elem;
		lp->capacity += LIST_INCREMENT;
		++lp->size;

	}
	else{                              //未满,插入元素
		for(int i=lp->size-1; i>=pos-1; --i){         //将元素后移,腾出位置
			lp->base[i+1] = lp->base[i];
		}
		
		lp->base[pos-1] = elem;                       //插入元素
		++lp->size;
	}
	return true;
}

bool remove_elem_pos(list_ptr *lp, const int pos)     //按位置删除
{
	assert(pos >= 1 && pos <= (*lp)->size);           
	
	for(value_ptr ptmp=&(*lp)->base[pos-1]; ptmp<&(*lp)->base[(*lp)->size-1]; ++ptmp)     
		*ptmp = *(ptmp+1);

	(*lp)->base[(*lp)->size-1] = 0;
	--(*lp)->size;
	
	return true;
}

bool remove_elem_val(list_ptr *lp, value_type elem)   //按值删除
{
	for(int i=0; i<(*lp)->size; ++i)
		if((*lp)->base[i] == elem){
			for(int j=i; j<(*lp)->size-1; ++j)        //所有符合要求的值都被删除
				(*lp)->base[j] = (*lp)->base[j+1];
				
				(*lp)->base[(*lp)->size-1] = 0;
				--(*lp)->size;
		}
	return true;
}

bool remove_elem(list_ptr lp, const void* clue, DELETE_MODE mode)   //外部接口,第三个参数选择按位置或按值删除模式
{
	assert(lp != NULL);

	if(list_empty(lp)){        //表空,不能删
		fprintf(stdout, "already empty, can not remove.\n");
		return false;
	}
	
	if(mode == POSITION){      //参数为POSITION,按位置删除
		remove_elem_pos(&lp, *(int *)clue);
	}
	else{                      //否则按值删除
		remove_elem_val(&lp, *(value_ptr)clue);     
	}

	return true;
}

void print_list(const seq_list sl)     //打印函数
{
	if(sl.size == 0)
		fprintf(stdout, "nil list.");

	for(int i=0; i<sl.size; ++i)
		printf("%f ", sl.base[i]);
	printf("\n");
}

int compare(const void *vp1, const void* vp2)      //比较函数
{
	return *(value_ptr)vp1 - *(value_ptr)vp2;
}

int locate_elem(const seq_list sl, const value_type elem, 
							       int (*compare)(const void *, const void *))   //定位函数
{
	if(list_empty(&sl)){
		fprintf(stdout, "list empty, con not locate.\n");
	}
	else{
		for(int i=0; i<sl.size; ++i)
			if((*compare)(&sl.base[i], &elem) == 0)         //相等则找到,返回位置
				return i+1;
	}
	return 0;
}

void sort_list(list_ptr lp, int (*compare)(const void *, const void *))     //排序函数
{
	assert(lp != NULL);
	qsort(lp->base, lp->size, sizeof(value_type), compare);                 //调用系统快速排序
}

void merge_list(list_ptr lpa, list_ptr lpb, list_ptr combine,
							  int (*compare)(const void *, const void *))   //合并两个顺序表
{
	assert(lpa != NULL && lpb != NULL && combine != NULL);

	combine->base = (value_ptr)malloc(sizeof(value_type)
											*(lpa->size+lpb->size));        //此处为新表申请空间,因此新表无需另外调用初始化函数,否则会发生内存泄漏
	assert(combine->base != NULL);

	combine->capacity = combine->size = lpa->size+lpb->size;               
 
	value_ptr it_pc = combine->base;
	value_ptr it_pa=lpa->base;
	value_ptr it_pb=lpb->base; 
	
	while(it_pa<lpa->base+lpa->size && it_pb<lpb->base+lpb->size){          //由小到大插入新表
		if(compare(it_pa, it_pb) <= 0)
			*it_pc++ = *it_pa++;
		else
			*it_pc++ = *it_pb++;
	}

	while(it_pa < lpa->base+lpa->size)      //从上面while出循环只有两种情况,此处为pa为插完,pb已插完,pa剩余元素直接插入,天然有序
		*it_pc++ = *it_pa++;
	while(it_pb < lpb->base+lpb->size)      //同理,若pb剩有元素,直接插入,天然有序
		*it_pc++ = *it_pb++;
}

#endif /*seq_list*/
二:测试代码
为保证通用性,不用int,用float测试。
#include "seq_list.h"

#define ARRAY_SIZE 10

int main()
{
	value_type array[] = {39.1, 32.1, 10.1, 11.1, 22.1, 5.1, 36.1, 28.1, 46.1, 32.1};
	seq_list list;   //顺序表1
	
	init_list(&list);

	for(int i=0; i<ARRAY_SIZE; ++i)
		insert_elem(&list, 1, array[i]);
	printf("list:\n");
	print_list(list);
	
#if 1 
	int clue = 1;                  //按顺序删除,删除第一个元素
	//value_type clue = 32.1;      //按值删除,删除值为32.1的元素,需修改下面参数为VALUE
	printf("after remove:\n");
	remove_elem(&list, &clue, POSITION);
	print_list(list);
#endif
#if 1 
	int found = locate_elem(list, 22.1, compare);        //定位22.1元素所在位置
	if(found >= 1)
		fprintf(stdout, "found %f at the position %d\n", list.base[found-1], found);
	else
		fprintf(stdout, "not found.\n");
#endif
	
	sort_list(&list, compare);
	printf("list after sort:\n");
	print_list(list);

	value_type array2[] = {98.1, 65.1, 4.1, 86.1, 34.1, 21.1, 86.1, 74.1, 93.1, 46.1};
	seq_list list2;

	init_list(&list2);
	for(int i=0; i<ARRAY_SIZE; ++i)
		insert_elem(&list2, 1, array2[i]);  
	printf("list2:\n");
	print_list(list2);
	
	printf("list2 after sort:\n");
	sort_list(&list2, compare);
	print_list(list2);

	seq_list new_list;   //无需调用init函数初始化,因为新表在merge_list中会初始化。如果强行调用,那么会出现内存泄漏。
	
	merge_list(&list, &list2, &new_list, compare);
	printf("new merge_list:\n");
	print_list(new_list);
	
	free(list.base);
	free(list2.base);
	free(new_list.base);        //三个释放,防止内存泄漏
	
	return 0;
}

三:测试结果



计算机控制技术及应用 《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。 立即下载

相关推荐

430单片机实现三人投票表决器_基于单片机的五人表决器的设计

姚海云+马野摘要:本设计利用51单片机,按键开关模块,数码管显示模块和LED模块来实现一个简单的五人表决器的功能。按键开关模块中的键2~键6表示五个人,由5个人来投票,当同意的票数大于或者等于3人时,数码管显示同意的人数,说明表决通过。当表决的人数小于3时,数码管显示同意的人数。关键词:表决器;单片机;流水灯;数码管;矩阵键盘;时钟中图分类号:TP391 文献标识码:A 文章编号:1009-304...

weixin_33277215的博客 2558

数据结构代码实现(C语言)——顺序表定义、插入、删除、查找

基本操作InitList(&L):初始化表。构造一个空的线性表。用静态数组定义顺序表。由于数组的大小和空间已固定,一旦空间占满,再加入新的数据就会产生溢出。//顺序表定义——静态分配#define MaxSize 10 //定义最大长度//数组存储线性表int length;//定义表长}SqList;//初始化,初始值置为0//在C语言中不存在引用的,&表示的不是引用,仅仅是取地址符。i

weixin_44031944的博客 5437

Titans:谷歌新型神经记忆架构,突破 Transformer 长序列处理的瓶颈

Titans 是谷歌推出的新型神经网络架构,通过神经长期记忆模块突破 Transformer 在处理长序列数据时的瓶颈,支持并行计算,显著提升训练效率。

士多啤梨先生の博客 991

C语言顺序表增删改查操作演示

【代码】C语言顺序表增删改查。

zzj的博客 644

[arcgis插件]在批量出图时,如何把图层属性表以动态表格的形式插入到布局页面

在批量出图时,如何把图层属性表以动态表格的形式插入到布局页面。

坐听风雨 4563

Altium AD20差分对走线设置方法

AD20的PCB差分对走线设置 1、原理图添加差分对 先在原理图中,讲要设置差分对的网络对添加网络标签。 名称前面的内容要相同,后缀用 _P 和 _N 加以区分。 最后使用 放置差分对,将两个网络标记。 2、编译,更改到PCB 编译,更新到PCB,确认差分对网络的出现。 验证更改,执行更改。将改动更新到PCB中。 PCB中,可通过 右下角 Panels - 调出 PCB 显示。来对已添加的差分对进行查看。 这时原本的走线有一点点小问题,需要删掉原来走线,设置差分对规则,并重新布线。

Mark_md的博客 3万+

C 语言之泛型编程

泛型编程是一种编程范式,旨在编写与特定数据类型无关的代码,从而提高代码的复用性和灵活性。在 C++ 中,模板提供了直接支持泛型编程的语法。而在 C 中,C11 标准的新特性使我们能够实现类似的功能。C11 标准的新特性,特别是 _Generic 关键字,使得在 C 语言中实现泛型编程变得更加容易。通过结合使用宏定义、void* 和 _Generic,我们可以编写出与特定数据类型无关的代码,从而提高代码的复用性和灵活性。希望这篇博客能帮助您理解如何在 C11 中实现泛型编程。

Quintin的博客 1014

Unity——Scroll View 滑动居中、居中的放大、其他的缩小(支持横竖Scroll View)

一、效果 二、上代码,两种方式。 (第一种是在Update中用插值完成的,如果不想再项目中看到Update,下面的另一种改了一段用DoTween实现的,需要导入一下DoTween) using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using Unit...

SiReSo 7659

数据结构泛化操作

数据结构泛化操作

qq_65035655的博客 133

PCL 法向量夹角剔除错误匹配点对【2026最新版】

实现了一种简单的基于对应点法线角度的对应关系去除方法。博客长期更新,本文最新更新时间为:2026年5月24日。

点云侠的博客 41万+

华为OD机试2025A卷 - 分苹果(Java & Python& JS & C++ & C )

华为OD机试2025A卷 - 分苹果(Java & Python& JS & C++ & C )

算法大师! 720

【C语言】顺序表的创建

顺序表的代码实现

lixxkv的博客 1万+

QQ也能连接OpenClaw啦!手机QQ远程操控本地AI保姆级教程

2026年最新OpenClaw与QQ连接教程发布,支持手机远程操控本地AI。腾讯官方推出QQ Bot插件,无需服务器即可实现三步绑定。教程提供三种连接方案:新手首选的扫码连接(10分钟搞定)、稳定的QQ群机器人方案,以及公网接入方案。详细步骤包括版本更新、插件安装、扫码绑定和功能测试,并附常见问题解决方案。该功能让用户通过QQ指令即可实现文件整理、文档生成等电脑操作,真正实现"手机发指令,电脑自动干"。

通俗易懂学IT 592

c语言泛型模板与this指针

前言 上次我简单讲了一下c语言泛型的模板,这次详解C语言泛型模板的封装和this指针构造. 操作内容如下: #include <stdio.h> #include "template.h" #include "Array.h" int main() { /***************C语言泛型示例**********************/ var a=Array(...

qq_37822482的博客 1288

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

C实现看起来像泛型的顺序表

C实现顺序表

lcplayer的博客 165

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

C语言实现顺序表

c语言实现顺序表 线性表是最简单的数据结构,而顺序表又是最简单的线性表,其基本思想是用一段地址连续的储存单元依次存储线性表的数据元素,比如我们常用的一位数组,下面代码实现了顺序表的定义以及基本操作。 编译环境:vs2017。 运行试例: 贴代码如下: #include "stdio.h" #include "windows.h" #include "stdlib.h" #define MAXSI...

qq_42204238的博客 4万+

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

掌握顺序表:从概念到C语言实现

C语言实现顺序表的创建与增删改查操作

howard2005的专栏 2万+

C语言基于void*实现泛型容器化代码编程

基于C的泛型容器化编程

su_fei_ma_su的博客 1431

基于C语言实现泛型编程(抛砖引玉)

基于C语言实现泛型编程

su_fei_ma_su的博客 937

顺序表的C语言实现

C语言实现顺序表

Broken_x的博客 1442

顺序表—C语言实现数据结构

本期主要带大家一起学习顺序表,内容较为丰富,图文并茂

2201_76062618的博客 1879

顺序表【C语言实现】

线性表是由n(n>=0)个具有相同特性的数据元素的有限序列。作为一种在计算机科学中广泛应用的基础数据结构,常见的线性表有:顺序表、链表、栈、队列、字符串等逻辑结构:呈线性结构,及数据元素之间存在“一对一”的逻辑顺序,如同一条直线。物理结构:数据元素在计算机内中的实际存储位置(物理位置)不一定是连续的。存储实现:数组(顺序存储结构):数据元素存储在一片连续的地址空间中。链式结构(链式存储结构):数据元素分散存储,通过指针链接表示其逻辑顺序。

2301_80426325的博客 1048

C语言顺序表的简单实现

当我们想要使用⼤量使用同⼀类型的数据时,通过手动定义大量的独立的变量对于程序来说,可读性非常差,我们可以借助据的方式。数据结构是计算机存储、组织数据的方式。。数据结构反映数据的内部构成,即数据由那部分构成,以什么方式构成,以及数据元素之间呈现的结构。

2303_80472275的博客 1494

【C语言】从零开始:用C语言实现顺序表

欢迎来CILMY23的博客本篇主题为 从零开始:用C语言实现顺序表

cilmy23的note 1580

用C语言实现顺序表

介绍了如何用C语言实现一个动态顺序表,并且完成对顺序表的增删查改等查找及测试。同时介绍了线性表和顺序表的优缺点。

0xFFFFFFFF 1207

C语言实现顺序表的基本操作

数据结构老师给了几个接口,叫我们自己去实现顺序表的功能,感想就是顺序表实现起来比链表容易,但是还是要花费挺长的时间来构思,这一次的收获还是挺多的。

OnlyLove_KD的博客 2万+
上一篇: 图的拓扑排序、关键路径、最短路径算法 -- C++实现
下一篇: 使用scanf初始化指针
FreeeLinux
博客等级 码龄11年 421粉丝 356原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值