高级语言里的列表是最常用的数据结构,在C里造个轮子玩玩,C没有泛型,先用int练习。

Collection的ADT一般有hasnext,next,add, remove操作,List一般还加了removeat, insert等,然后Stack有push和pop,Queue有enqueue和dequeue。列表有种实现, ArrayList和LinkedList,总体来说ArrayList更常用一些,就先用数组实现个列表。

ArrayList在末尾的添加和删除还是挺快的(O(1)),所以当栈来用挺好,Push和Pop都在末尾。 当队列的话,Enqueue在数组头部放入元素,所有右边的元素都要向右移动(O(N)),比较耗 时,不如LinkedList。另外获取指定索引数据或设置指定索引的数据是O(1)复杂度, 比LinkedList快,如果要想查看是否有指定数据,或删除指定数据,要扫描全表,复杂度 是O(N)。哦,删除指定位置的数据复杂度也是O(N), 因为删除后右边的数据要全部向 左移动。

可以开始了,首先定义一个结构来保存状态

struct arr_list {
int * arr; // 内部数组
int index; // 实际数据大小
int size; // 预分配空间大小
};

创建一个array list

struct arr_list* create_arr_list(n) {
if (n < ) {
n = ;
}
struct arr_list *arr = (struct arr_list*)malloc(sizeof(struct arr_list));
arr->arr = (int*)malloc(sizeof(int) * n);
arr->size = n;
arr->index = ;
return arr;
}

空间不足时自动扩容,默认策略是空间不够时申请双倍大小空间, 然后把原有数据拷贝到 新空间,并把原有空间释放掉, 该函数一般是新增元素前调用,所以判断条件是当实际 所用空间已经等于或大于(应该不可能)预分配空间时扩容。

static void expand_space(struct arr_list *arr) {
int *tmp, i, *p, *q; if (arr->index >= arr->size) {
tmp = (int *)malloc(sizeof(int) * arr->size * );
p = arr->arr;
q = tmp;
for (i = ; i < arr->index; i++) {
*q++ = *p++;
}
free(arr->arr);
arr->arr = tmp;
arr->size = arr->size * ;
}
}

在指定位置插入新元素,现有元素向右移,O(N)

int list_insert(struct arr_list *arr, int index, int obj) {
int i; if (index < || index > arr->index) {
return -;
}
expand_space(arr); for (i = arr->index; i > index ; i--) {
arr->arr[i] = arr->arr[i - ];
}
arr->arr[index] = obj;
arr->index++;
return ;
}

在array list 末尾插入数据, O(1)

int list_push(struct arr_list *arr, int obj) {
return list_insert(arr, arr->index, obj);
}

删除指定位置的数据,O(N), 删除数据后,所有数据向左移动

int list_removeat(struct arr_list *arr, int index) {
int i;
if (index < || index >= arr->index) {
return -;
}
for (i = index; i < arr->index - ; i++) {
arr->arr[index] = arr->arr[index + ];
}
arr->index--;
return ;
}

移除并返回末尾的数据, O(1)

int list_pop(struct arr_list *arr) {
return list_removeat(arr, arr->index - );
}

判断 array list里是否包含某个数据, O(N)

int list_index(const struct arr_list *arr, int obj) {
int i;
for (i = ; i < arr->index; i++) {
if (arr->arr[i] == obj) {
return i;
}
}
return -;
}

删除某个数据项,O(N), 只删第一次出现的位置, 删除后所有数据向左移动

int list_remove(struct arr_list *arr, int obj) {
int i, index;
index = list_index(arr, obj);
if (index != -) {
for (i = index; i < arr->index - ; i++) {
arr->arr[i] = arr->arr[i + ];
}
arr->index--;
}
return index;
}

释放一个array list的内存

int free_arr_list(struct arr_list *arr){
free(arr->arr);
free(arr);
return ;
}

从头打印一个arr list

void print_arr_list(const struct arr_list *arr) {
int i, t;
printf("size=%d,index=%d\n", arr->size, arr->index);
for (i = ; i < arr->index; i++) {
list_get(arr, i, &t);
printf("list[%d]=%d\n", i, t);
}
}

最后整体测试一下

int main(void)
{
struct arr_list *arr;
int r; arr = create_arr_list();
printf("list push: 5, 6, 7\n");
list_push(arr, );
list_push(arr, );
list_push(arr, );
print_arr_list(arr); printf("list push: 8, will auto expand\n");
list_push(arr, );
print_arr_list(arr); printf("list remove at 2\n");
list_removeat(arr, );
print_arr_list(arr); printf("list pop \n");
list_pop(arr);
print_arr_list(arr); printf("list insert 0\n");
list_insert(arr, , );
print_arr_list(arr); r = list_index(arr, );
printf("list index 3:%d\n", r);
r = list_index(arr, );
printf("list index 7:%d\n", r); printf("list remove 3\n");
list_remove(arr, );
print_arr_list(arr); printf("list set index 0 = 3\n");
list_set(arr, , );
print_arr_list(arr); free_arr_list(arr);
return ;
}

小结

用C实现一下高级语言里常用的数据结构,可以对它们有更深的理解。

快速学习C语言四: 造轮子,ArrayList的更多相关文章

  1. 快速学习C语言一: Hello World

    估计不会写C语言的同学也都听过C语言,从头开始快速学一下吧,以后肯定能用的上. 如果使用过其它类C的语言,如JAVA,C#等,学C的语法应该挺快的. 先快速学习并练习一些基本的语言要素,基本类型,表达 ...

  2. 快速学习C语言三: 开发环境, VIM配置, TCP基础,Linux开发基础,Socket开发基础

    上次学了一些C开发相关的工具,这次再配置一下VIM,让开发过程更爽一些. 另外再学一些linux下网络开发的基础,好多人学C也是为了做网络开发. 开发环境 首先得有个Linux环境,有时候家里机器是W ...

  3. 快速学习C语言二: 编译自动化, 静态分析, 单元测试,coredump调试,性能剖析

    上次的Hello world算是入门了,现在学习一些相关工具的使用 编译自动化 写好程序,首先要编译,就用gcc就好了,基本用法如下 gcc helloworld.c -o helloworld.o ...

  4. 快速学习C语言途径,让你少走弯路

    1.标准C语言能干什么? 坦白讲,在今天软件已经发展了半个多世纪,单纯的C语言什么都干不了.标准C语言库只提供了一些通用的逻辑运算方法以及字符串处理,当然字符串在C语言看来也是一种操作内存的方法,所以 ...

  5. 造轮子ArrayList

    这篇博客实现一个简单的ArrayList集合.博客里的代码首先根据自己的想法实现,在走不动的情况下会去参考JDK源代码.所以阅读本文,不要抱着跟JDK源码对比的心态.于我个人而言,国庆期间,纯属娱乐. ...

  6. Vue快速学习_第四节

    获取原生的DOM方式($.refs) 给标签或者组件 添加ref <div ref = 'liu'>test</div> <Home ref = 'home'>&l ...

  7. 一起学习造轮子(一):从零开始写一个符合Promises/A+规范的promise

    本文是一起学习造轮子系列的第一篇,本篇我们将从零开始写一个符合Promises/A+规范的promise,本系列文章将会选取一些前端比较经典的轮子进行源码分析,并且从零开始逐步实现,本系列将会学习Pr ...

  8. 如何快速高效率地学习Go语言

    要想快速高效率地掌握Go语言,关键是要通过不断写代码去训练,熟能生巧.方法是没问题的,但具体的路径呢?就像开车,能不能给个导航?我希望这篇文章能起到一个导航的作用,这里提供的路径,应该对很多人都适合. ...

  9. c语言学习之第四章

    第四章 第四章主要介绍了分支结构,循环结构的简单使用,还有其他简单的语句结束语句,比如,break,continue.还有gote语句.下面是我学习C语言第四章的一些心得和总结. 1简单的if语句 简 ...

随机推荐

  1. Android开发工具全面转向Android Studio(3)——AS project/module的目录结构(与Eclipse对比)

    如果AS完全还没摸懂的,建议先看下Android开发工具全面转向Android Studio(2)——AS project/module的CRUD. 注:以下以Windows平台为标准,AS以目前最新 ...

  2. 在本地创建angular-ui/bootstrap项目

    在本地创建完整的angular-ui/Bootstrap项目 git clone the repo, then switch to the tag you want,then use grunt bu ...

  3. textField和textView限制输入条件

    以下两法方法都是实现textfield和textView的代理方法  需要先遵循代理 一:textField限制只能输入数字和小数点 且小数点后只能保留两位 小数点前最多5位 - (BOOL)text ...

  4. H5学习系列之Geolocation API

    获取位置信息途径: 1.IP地址地理定位数据 2.GPS地理定位数据 3.WI-FI地理定位数据 4.手机地理定位数据 无废话直接上重点:navigator.geolocation对象就是获取地理位置 ...

  5. 3. Builder(建造者)

    意图: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 适用性: 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时. 当构造过程必须允许被构造的对象有不同 ...

  6. 接收新信息,在会话中看不到(thread表数据插入/更新失败)

    分析原因:收到短信,sms表插入信息,触发器会自动更新thread表,更新失败导致一直有一条未读信息数量显示,但在会话列表中却看不到. (偶现,低概率. 解决方法:接收新信息插入后,立即查询threa ...

  7. node学习笔记(三)

    //事件驱动events //events是node最重要的模块没有之一,因为node.js本身的架构就是事件式的,而他提供了唯一的接口,所以堪称node.js事件编程的基石; //events几乎被 ...

  8. img 是内联元素

    图片是内联元素 ,同时是内联替换元素(替换元素是能设置宽和高的) 取消图片的magin display:block;(一般初始化标签中会把图片设置成块状) replaced element <i ...

  9. JS-concat

    var arr1 = [ 1,2,3 ];var arr2 = [ 4,5,6 ];var arr3 = [ 7,8,9 ];alert( arr1.concat( arr2, arr3 ) );

  10. 在虚拟机上安装Linux6.5

    下定决心开始学习Linux了,这个博客将记录我的成长点滴,方便日后温故而知新!并希望有小伙伴能给出意见和建议! 我用的是VMware Workstation 10,当然是破解版,毕竟只是自己做练习使用 ...