变长数组列表ArrayList
简介:此数据结构定义为一个ArrayList结构体类型,维护了一个内部堆数组。通过realloc函数实现了数组容量自动扩充,每次扩充到原来的2倍。
通过函数指针实现了使用者根据自己的需求按条件按查找目标元素的功能,查找筛选函数需要使用者自行编写。
支持的主要操作:
追加Append
插入Insert
删除Delete
访问GetElement
写入SetElement
查找Find
FindAll
裁剪TrimToSize
销毁Destroy
/*
file : ArrayList.h
*/
#ifndef _ARRAYLIST_H_
#define _ARRAYLIST_H_
typedef int ElemType; //存储的数据的类型
typedef int(*FindFunc)(ElemType); //定义一个函数指针类型 FindFunc,作为查找函数 的类型
typedef struct {
ElemType *p_inner_arr; //指向数组第一个元素的指针
int length; //表中实际元素个数
int capacity; //表的容量
}ArrayList;
void InitList(ArrayList* plist,int c);
void TrimToSize(ArrayList* plist) ;
int Insert(ArrayList* plist,ElemType x,int index);
void Append(ArrayList* plist,ElemType x);
int Delete(ArrayList* plist,ElemType* px,int index);
ElemType GetElement(ArrayList*plist , int index);
void SetElement(ArrayList*plist , ElemType x, int index);
int IsEmpty(ArrayList *plist);
int Find(ArrayList *plist, FindFunc func);
ArrayList* FindAll(ArrayList *plist, FindFunc func);
void Destroy(ArrayList*plist);
#endif
/* file : ArrayList.cpp
*/
#include<stdlib.h>
#include "ArrayList.h"
/*初始化数组列表
*/
void InitList(ArrayList* plist,int c)
{
plist->capacity = c; //初始化容量
plist->length = ; //初始化实际长度
plist->p_inner_arr = (ElemType*)malloc(c * sizeof(ElemType)) ;
//分配初始内存空间
//假设这里malloc 总成功
}
/*裁剪多于的 没有存放数据的内存空间 。即length == capacity
*/
void TrimToSize(ArrayList* plist)
{
) return ;
if(plist->length < plist->capacity)
{ //realloc实现堆内存的大小调整,大小可增,也可以减,它会返回调整大小后的内存的新地址。重新赋值给p_inner_arr
plist->p_inner_arr = (ElemType*)realloc(plist->p_inner_arr,plist->length*sizeof(ElemType));
plist->capacity = plist->length;
}
}
/*追加或者插入都可以
增加失败返回 false
*/
int Insert(ArrayList* plist,ElemType x,int index)
{
|| index > (plist->length) ) //索引不合法
;
if(plist->length >= plist->capacity) //表已经饱和
{
plist->p_inner_arr = (ElemType*)realloc(plist->p_inner_arr, plist->length**sizeof(ElemType));
plist->capacity = plist->length*;
}
; i>=index ; --i )
{
plist->p_inner_arr[i+] = plist->p_inner_arr[i];
}
plist->p_inner_arr[index] = x; //插入
++(plist->length); //增加表长度
;
}
/* 追加
*/
void Append(ArrayList* plist,ElemType x)
{
if(plist->length >= plist->capacity) //表已经饱和,无法容纳
{
plist->p_inner_arr = (ElemType*)realloc(plist->p_inner_arr, plist->length**sizeof(ElemType));
plist->capacity = plist->length*;
}
plist->p_inner_arr[plist->length] = x;
++(plist->length);
return ;
}
/*删除某个元素
删除失败返回false
*/
int Delete(ArrayList* plist,ElemType* px,int index)
{
) ;
|| index > (plist->length-)) ;
if(px!=NULL) *px = (plist->p_inner_arr)[index];
/*数据结构的使用者可以选择是否需要保存
这个被删除的元素,不需要则传入NULL
*/
; ++i) //前移
{
plist->p_inner_arr[i] = plist->p_inner_arr[i+];
}
--(plist->length);
;
}
ElemType GetElement(ArrayList*plist , int index)
{
return plist->p_inner_arr[index];
}
void SetElement(ArrayList*plist , ElemType x, int index)
{
|| index> plist->length ) return ;
plist->p_inner_arr[index] = x;
}
//状态判断
int IsEmpty(ArrayList *plist)
{
;
}
/*按条件查找
条件函数由使用者自行编写,这个函数接受一个ElemType类型参数,并返回1 or 0
一旦找到了符合条件的元素,就返回它的索引,没找到,则返回 -1
*/
int Find(ArrayList *plist, FindFunc func)
{
; i<plist->length ; ++i)
{
if(func(plist->p_inner_arr[i]))
return i;
}
;
}
/* 按条件查找所有符合的元素
*/
ArrayList* FindAll(ArrayList *plist, FindFunc func)
{
ArrayList*tlist ; //新建一个Arraylist对象,用来保存符合条件的元素
InitList(tlist,) ;
; i<plist->length; ++i)
{
if(func(plist->p_inner_arr[i]))
Append(tlist,plist->p_inner_arr[i]);
}
) //没有找到任何符合要求的元素
{
Destroy(tlist);
return NULL;
}
TrimToSize(tlist);
return tlist;
}
void Destroy(ArrayList*plist)
{
free(plist->p_inner_arr);
plist->p_inner_arr = NULL;
plist->length=;
plist->capacity=;
}
心得:
1、还是面对对象好,主要优势很明显:数据对象的自描述性和自操作性,也就是一个数据的属性和操作都在"自己身"上找到,还有封装会使数据结构更加完美,安全。
2、数据结构需要的通用性要好,而C本身不支持泛型编程,但是在编写代码的时候可以优化代码的通用性,这样使用不同目标数据类型时,只需要做很少的修改。
3、还是C语言写起来有感觉些,简洁,自由,哈哈。
变长数组列表ArrayList的更多相关文章
- C++内存分配及变长数组的动态分配
//------------------------------------------------------------------------------------------------ 第 ...
- oracle:变长数组varray,嵌套表,集合
创建变长数组类型 ) ); 这个变长数组最多可以容纳两个数据,数据的类型为 varchar2(50) 更改元素类型的大小或精度 可以更改变长数组类型和嵌套表类型 元素的大小. ALTER TYPE ...
- C99新增内容之变长数组(VLA)
我们在使用多维数组是有一点,任何情况下只能省略第一维的长度.比如在函数中要传一个数组时,数组的行可以在函数调用时传递,当属数组的列却只能在能被预置在函数内部.看下面一个例子: #define COLS ...
- GCC 中零长数组与变长数组
前两天看程序,发现在某个函数中有下面这段程序: int n; //define a variable n int array[n]; //define an array with length n 在 ...
- C99新特性:变长数组(VLA)
C99标准引入了变长数组,它允许使用变量定义数组各维.例如您可以使用下面的声明: ; ; double sales[rows][cols]; // 一个变长数组(VLA) 变长数组有一些限制,它必须是 ...
- PL/SQL — 变长数组
PL/SQL变长数组是PL/SQL集合数据类型中的一种,其使用方法与PL/SQL嵌套表大同小异,唯一的区别则是变长数组的元素的最大个数是有限制的.也即是说变长数组的下标固定下限等于1,上限可以扩展.下 ...
- PL/SQL 嵌套表变长数组和索引表[转]
关于PL/SQL中这三种数组的介绍,不想写了.转一篇日志吧…… 链接:http://www.blogjava.net/decode360/archive/2008/08/08/280825.html ...
- c语言,变长数组
下面这个结构体,可以在malloc的时候指定数据data的长度,这样的形式就是变长数组:typedef struct{ int data_len; char data[0];//或char data[ ...
- C99中的变长数组(VLA)
处理二维数组的函数有一处可能不太容易理解,数组的行可以在函数调用的时候传递,但是数组的列却只能被预置在函数内部.例如下面这样的定义: #define COLS 4 int sum3d(int ar[] ...
随机推荐
- Xamarin Visual Studio提示找不到AssemblyAttributes.cs文件
Xamarin Visual Studio提示找不到AssemblyAttributes.cs文件 错误信息:Could not find file ‘C:\Users\[用户名]\AppDat ...
- JavaScript有哪些延迟加载的方式?
defer和async,动态创建DOM方式(用得最多),按需异步载入js.
- SplendidCRM 中文语言包改正版
由于官方的中文语言包太多地方词不达意,可能是文化差异吧,如“删除”却写成“德尔”.本人修改了几十个地方,还修改了不能清除已有数据的Bug.相关文件在下载包中. http://files.cnblogs ...
- HDU1853 & 蜜汁建图+KM模板
题意: 给你一个N个点M条边的带权有向图,现在要你求这样一个值:该有向图中的所有顶点正好被1个或多个不相交的有向环覆盖.这个值就是 所有这些有向环的权值和. 要求该值越小越好. SOL: 本来还想ta ...
- 移动互联网终端的touch事件,touchstart, touchend, touchmove
如果我们允许用户在页面上用类似桌面浏览器鼠标手势的方式来控制WEB APP,这个页面上肯定是有很多可点击区域的,如果用户触摸到了那些可点击区域怎么办呢??诸如智能手机和平板电脑一类的移动设备通常会有一 ...
- 【wikioi】1022 覆盖(匈牙利)
http://www.wikioi.com/problem/1022/ 好不容易来一次1A,,水题啊.. 染色后裸匈牙利orz #include <cstdio> #include < ...
- BZOJ3772: 精神污染
Description 兵库县位于日本列岛的中央位置,北临日本海,南面濑户内海直通太平洋,中央部位是森林和山地,与拥有关西机场的大阪府比邻而居,是关西地区面积最大的县,是集经济和文化于一体的一大地区, ...
- Qt中图像的显示与基本操作
Qt可显示基本的图像类型,利用QImage.QPxmap类可以实现图像的显示,并且利用类中的方法可以实现图像的基本操作(缩放.旋转). 1. Qt可显示的图像类型 参考Qt的帮助文档,可支持的类型,即 ...
- dig 命令详解(转载) - 阿权的书房
在 unix 和 linux 下,建议大家使用 dig 命令来代替 nslookup. dig 命令的功能比 nslookup 强大很多,不像 nslookkup 还得 set 来 set 去的,怪麻 ...
- [IT学习]PowerBi 入门
从哪里开始呢?注册一个账号,从PowerBi的help开始就行了.Get Started会带领你从get data讲起,建立dataset,建立report,一直到dashboard创建. 下面这个链 ...