变长数组列表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[] ...
随机推荐
- Marvelous Mazes
F - Marvelous Mazes Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submi ...
- 使用 IL 实现类型转换
在之前的文章中,我大致介绍过一些类型间的隐式和显式类型转换规则.但当时并未很仔细的研究过<CSharp Language Specification>,因此实现并不完整.而且只部分解决了类 ...
- 新旧各版本的MySQL可以从这里下载
http://downloads.mysql.com/archives/
- css3中的几何图形shape研究
前言 估计大家在日常工作中都会用到css形状,但是目前天朝中使用到最多的估计就是圆(circle).椭圆(ellipse).各种三角形形状,但是你肯定很少看见过用几何图形或者多边图形.假如你不懂什么叫 ...
- BZOJ4260: Codechef REBXOR
Description Input 输入数据的第一行包含一个整数N,表示数组中的元素个数. 第二行包含N个整数A1,A2,…,AN. Output 输出一行包含给定表达式可能的最大值. S ...
- C# params object[] args 可以传多个参数,可以不限制类型(转)
C# params object[] args 可以传多个参数,可以不限制类型 using System;using System.Collections.Generic;using System.T ...
- Html - Bootstrap 头部
<div class="container"> <div class="row clearfix"> <div class=&qu ...
- Office 2010 KMS激活原理和案例分享 - Your Office Solution Here - Site Home - TechNet Blogs
[作者:葛伟华.张玉工程师 , Office/Project支持团队, 微软亚太区全球技术支持中心 ] 为了减低部署盗版(可能包含恶意软件.病毒和其他安全风险)的可能性,Office 2010面向企 ...
- GC-垃圾回收
代:0代,1代,2代: 所谓第几代,指经历过GC回收的次数. 回收算法: 1.确认需要检查的代. 在分配新对象时, 如果第0代已满,则进行检查:如果第1代已满,则进行检查:第2代同理: 如第0代没有足 ...
- flowvisor test(1)
参考: Flowvisor 入门 杨帅老师:mininet+FlowVisor+ODL环境搭建及实验1 安装: 参考: 1.Flowvisor安装 2.Mininet安装 3.官网,Floodligh ...