简介:此数据结构定义为一个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的更多相关文章

  1. C++内存分配及变长数组的动态分配

    //------------------------------------------------------------------------------------------------ 第 ...

  2. oracle:变长数组varray,嵌套表,集合

    创建变长数组类型 ) );  这个变长数组最多可以容纳两个数据,数据的类型为 varchar2(50) 更改元素类型的大小或精度 可以更改变长数组类型和嵌套表类型 元素的大小. ALTER TYPE ...

  3. C99新增内容之变长数组(VLA)

    我们在使用多维数组是有一点,任何情况下只能省略第一维的长度.比如在函数中要传一个数组时,数组的行可以在函数调用时传递,当属数组的列却只能在能被预置在函数内部.看下面一个例子: #define COLS ...

  4. GCC 中零长数组与变长数组

    前两天看程序,发现在某个函数中有下面这段程序: int n; //define a variable n int array[n]; //define an array with length n 在 ...

  5. C99新特性:变长数组(VLA)

    C99标准引入了变长数组,它允许使用变量定义数组各维.例如您可以使用下面的声明: ; ; double sales[rows][cols]; // 一个变长数组(VLA) 变长数组有一些限制,它必须是 ...

  6. PL/SQL — 变长数组

    PL/SQL变长数组是PL/SQL集合数据类型中的一种,其使用方法与PL/SQL嵌套表大同小异,唯一的区别则是变长数组的元素的最大个数是有限制的.也即是说变长数组的下标固定下限等于1,上限可以扩展.下 ...

  7. PL/SQL 嵌套表变长数组和索引表[转]

    关于PL/SQL中这三种数组的介绍,不想写了.转一篇日志吧…… 链接:http://www.blogjava.net/decode360/archive/2008/08/08/280825.html ...

  8. c语言,变长数组

    下面这个结构体,可以在malloc的时候指定数据data的长度,这样的形式就是变长数组:typedef struct{ int data_len; char data[0];//或char data[ ...

  9. C99中的变长数组(VLA)

    处理二维数组的函数有一处可能不太容易理解,数组的行可以在函数调用的时候传递,但是数组的列却只能被预置在函数内部.例如下面这样的定义: #define COLS 4 int sum3d(int ar[] ...

随机推荐

  1. ural 1218. Episode N-th: The Jedi Tournament

    1218. Episode N-th: The Jedi Tournament Time limit: 1.0 secondMemory limit: 64 MB Decided several Je ...

  2. BZOJ3073 : [Pa2011]Journeys

    用线段树套链表维护所有边,用set维护未访问过的点 然后BFS,每次在线段树上找边,然后在set中查询点 一条边使用之后就没有用了,所以在链表中将它删去 时间复杂度$O((n+m)\log n+m\l ...

  3. storm源码之理解Storm中Worker、Executor、Task关系 + 并发度详解

    本文导读: 1 Worker.Executor.task详解 2 配置拓扑的并发度 3 拓扑示例 4 动态配置拓扑并发度 Worker.Executor.Task详解: Storm在集群上运行一个To ...

  4. 【wikioi】1010 过河卒

    题目链接 算法:DFS+剪枝 14.01.02 PS: 递推应该也可以的,改天看看 刚开始最容易想到的是朴素搜索 #include <iostream> using namespace s ...

  5. Java中替换HTML标签的方法代码

    这篇文章主要介绍了Java中替换HTML标签的方法代码,需要的朋友可以参考下 replaceAll("\\&[a-zA-Z]{0,9};", "").r ...

  6. C# 取整

    double a = 1.1478; Math.Celling(a): 向上取整,结果为2 Math.Float(a); 向下取整,结果为1 Math.Round(a,2);  保留两位小数的奇进偶舍 ...

  7. gif 录制 屏幕 工具

    写博客或者提出问题时,很多时候需要gif才能说明问题 window录制攻略 https://pan.baidu.com/s/1gdCX1Gf mac录制攻略 第一步:打开mac内置的播放器QuickT ...

  8. 3种用组策略将域帐号加入本地管理员组的方法_jinifly_新浪博客

    次当前系统域帐号是怎么在第一次登录时,自动加入域客户端本地管理员组的?我猜不外乎就是脚本.计算机策略或虚拟机初始化的自动应答脚本,结果系统的前任同事找到了答案--GPO的用户策略(确切讲是用户首选项) ...

  9. 【液晶模块系列基础视频】4.5.X-GUI图形界面库-进度条等函数简介

    [液晶模块系列基础视频]4.5.X-GUI图形界面库-进度条等函数简介 ============================== 技术论坛:http://www.eeschool.org 博客地址 ...

  10. POJ 2777 Count Color(线段树染色,二进制优化)

    Count Color Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 42940   Accepted: 13011 Des ...