JAVA中ArrayList的底层基本实现
来源:互联网 发布:ec软件使用 编辑:程序博客网 时间:2024/05/16 01:19
/* 我不想做码农,那就学学算法吧*//* 1.实现一个简单的Arraylist。 Arraylist的功能有如下 a.增加元素 Ok b.查找元素 c.修改元素 4.查找元素 而且他是有下标的,也就是类似操作一个数组. 线性表这里面我们暂时不使用动态扩容了,在链表的时候我们在采取动态扩容的方法*/#define MAX_SIZE 103 //设置最大存储容量为20#define INIT_SIZE 5 //初始的存储容量为5typedef int Element;// 设置一下变量的类型.以后用Element来代替int,作用我也不是很清楚待查...#include <stdio.h>#include <stdlib.h>/* 代码步骤分析 1.我们首先要创建一个线性表,那么我们就需要去查看 我们的链表是否存在 a.存在我们就把链表取出来,之后继续下面的操作 b.不存在那么就需要我们去创建一个链表 在这之前我们需要了解一些 东西 指针的操作 eg: int *p; int a=10; p=&a; 把a的地址给了p,p就是a的地址,之后采用*运算符去把地址里面的值取出来 我们来实践一下 想到还是指针操作的方便*/typedef struct{ /* 这里面的参数就值得商议了 首先一定要有一个element 类型的指针了,用来存储变量的信息 其次,还需要知道现在存储的是第几个值.以及 (数据结构与我们评出所基础的数组有一点点不同.是给人看的.不能从0开始查) */ Element *data; int length; int maxSize;//当前存储的最大容量 /* 如果说像我这么定义的话那么只能够存储一位整数. */}Sql_L; /* 写到这里发现了一个问题.我们可以在一开始main函数刚刚进来的时候,就先调用这个函数 判断的方法判断他的长度是否为0 写到这里我也有一些疑惑(可能是学java写太长时间了.都不清楚c语言中能不能调用.length...- -!) 数组以'\0'为结束标志,一般可以通过此方法求出数组(有用数据的)长度,数组长度是定义的,一般不用求的。 当然也可以通过数组内存空间大小来求数组长度, 如:sizeof函数也可以求数组大小 我们需要去加一个函数用去求数组的长度的函数getLength(); 下面我们去写如何初始化一个线性表 *///实现线性表的初始化int initArrayList(Sql_L *ArrayList )//好像传出的需要是这个类型的数据{ //算了,既然用到了初始化线性表那么还是 来写一个动态赋予吧.不是动态赋予的话很简单 简单的查了一下 可以new ArrayList->data = (Element *)malloc(sizeof(Element *)*INIT_SIZE); if(ArrayList->data == NULL) { printf("初始化失败,程序即将推出!"); exit(0); } else { ArrayList->length = 0; ArrayList->maxSize =MAX_SIZE; printf("初始化成功!"); return 1;//这样传出的话,传出的是一个地址! }}//获取线性表的长度int getLength(Sql_L *L){ /*思考我们该如何去确定一个指针里面到底有没有值 如果说是一个数组的花那么很好办 有两种方法 作为一个指针可以用.length么?显然是不可以的 好吧!他有.length方法 */ return L->length;}/* E remove(int index) 移除此列表中指定位置上的元素。 boolean remove(Object o) 移除此列表中首次出现的指定元素(如果存在)。 *///第一种移除方式int removeElementByIndex(Sql_L *L){ //移出的下标,我们需要去判断一下 int index; int i; //我们按照下表进行演示 printf("请输入你要删除的位置:"); scanf("%d",&index); if(index < 0 || index > L->length-1) { return -1; } //如果下标符合操作的话,下面还是移动的操作,不过这次是向前移动了 for(i = index; i < L->length-1 ; i++) { (L+i)->data=(L+i+1)->data; } L->length--; return 1;}// 删除该元素第一次出现的位置int removeElementByIndexFirst(Sql_L *L){ //移出的下标,我们需要去判断一下 int index; int value; int i; printf("请输入你要删除的元素:(删除第一次出现的)"); scanf("%d",&value); //我们按照下表进行演示 for(i = 0; i < L->length; i++) { if((L+i)->data == value) { //当拿到第一个出现的下标就退出 index = i;break; } } //如果下标符合操作的话,下面还是移动的操作,不过这次是向前移动了 for(i = index; i < L->length-1 ; i++) { (L+i)->data=(L+i+1)->data; } L->length--; return 1;}//插入元素(尾部)int insertElement(Sql_L *L){ //下节课再说.我们来听一首歌先 //加到后面我们不用去考虑那么多.直接怼就可以不过我要知道到底加到第几个 //我就是想知道而已.然后回一下汇编 看能不能找到我刚刚插进去的数字 int local = L->length; if(L->length >=20) { printf("容量已经满了,需要扩容了!"); /* 下面应该写一个动态扩容的函数 */ return -1; } else { int element;//初始化 与 不初始化的区别在哪里? printf("请输入你要插入的数字:(选择的第一种很方式为追加到元素的尾部)"); /* 果然这个里面出错了*/ scanf("%d",&element); printf("element的值位:%d",element); (L+local)->data=element; L->length++; return 1; } //我还是需要判断下长度的}/* 下面写一下线性表中的set 函数 set(int index, E element) 用指定的元素替代此列表中指定位置上的元素。 *///修改指定下标元素的值int setElement(Sql_L *L){ int local; int value; //替换的位置我们需要 判断一下 printf("请输入你要替换的位置:"); scanf("%d",&local); printf("请输入你要替换的值:"); scanf("%d",&value); if(local < 0 || local > L->length - 1) { return -1; } //没有什么难的.说白了 就是做一个值得替换 (L+local)->data = value; return 1;}//插入一个特定位置的元素int insertElementByLocal(Sql_L *L){ /* 我们先需要判断他插入的位置合理不合理*/ int i = 0; int local_Length = 0; int value = 0; printf("请输入你要插入的位置:\n"); scanf("%d",&local_Length); printf("请输入你要插入的值:\n"); scanf("%d",&value); if(local_Length < 0 || local_Length > L->length) // 当插入的位置等于最大长度的话是可以插入的.类似于直接插入到线性表的最后面 { //在我的这里面1代表 程序没问题 0代表程序出错 return -1; } /* 插入得时候这个数组长度.我是先加一 还是后加一.这是一个问题. c语言中好像存在这样一种机制可以跨越直接给地址赋值 但问题是:会不会影响其他的内容造成内存的溢出,好在 指针就是一个类似于数组的玩意以'\0'作为判断他是否是最后一个 所以我们选择先插入后面再++ 一会在测试一下,如果先加了会怎么样. 注释:插入的位置我们让他以计算机的思维吧 */ //从最后面依次向前移动 //去测试一下数组的移动 //还是先加1把 L->length++; for(i=L->length-1;i > local_Length;i--) { (L+i)->data = (L+(i-1))->data; } (L+local_Length)->data=value; return 1;}/* 下面的元素用于查找元素是否存在 如果存在则返回他的下标 如果不存在则返回-1*///搜索元素的下标存在不存在int searchElement(Sql_L *L){ int Element; int i; printf("请输入你要查找的元素:\n"); scanf("%d",&Element); for( i = 0; i < L->length; i++) { if((L+i)->data == Element) { //返回的是下标 printf("查找到的下标为:%d",i); return i; } } return -1;}//遍历线性表void prior(Sql_L *L){ //先获取他的长度 int i ; for(i = 0; i < L->length; i++) { printf("当前的长度为:%d",L->length); printf("\n"); /* 需要将一个首地址传过来*/ printf("当前的数值为:%d",(L+i)->data); // *(L.data+i-1) }}/* 把所有写好的函数都放在上面这样并无耽误事.不然以后还需要在上面声明一下神烦.*/int main(){ /*刚刚写好初始化的部分问题就来了.我竟然不知道如何去使用这个*ArrayList变量,先拿过来直接用试试*/ //我是地址你也是地址,咱俩可以直接用地址进行交互没毛病吧! /* 接下来如何去连接这是一个问题 */ /* 调用出错,我们应考虑 怎么把定义过的结构体类型拿过来用以及 在动态创键一个数组的时候到底该返回什么*/ Sql_L *ArrayList; int length; int choice; int status; //标志变量 int FLAG = 1; int insertElement_status; int backStatus = 1; //这个步骤是用来给线性表做初始化的 initArrayList(&ArrayList); while(FLAG) { printf("请输入你的选择:"); scanf("%d",&choice); switch(choice) { // 1我们用来显示插入到尾部的操作 case 1: status = insertElement(&ArrayList);break; // 2我们用来做固定位置的插入 case 2: status = insertElementByLocal(&ArrayList);break; // 3我们用来描述关于数据的查找. case 3: status = searchElement(&ArrayList);break; //用于替换特定位置特定的值 case 4: status = setElement(&ArrayList);break; //删除元素按照数组下标进行删除 case 5:status = removeElementByIndex(&ArrayList);break; //删除元素第一次出现的指定的元素 case 6: status = removeElementByIndexFirst(&ArrayList);break; // 8我们用来描述线性表的遍历 case 8: prior(&ArrayList);break; } if(status == -1) { printf("操作出了问题,请审查!"); } else { printf("继续操作请输入任意数字(输入0则退出):"); scanf("%d",&FLAG); } getchar(); } /* 传入的地址出现了问题 */ /* 插入数据*//* if(insertElement_status == 1) { printf("添加成功!"); } else { printf("添加数据失败!"); }*/ /* while(backStatus) { backStatus = insertElementByLocal(&ArrayList); prior(&ArrayList); }*/ /* 接下来是遍历函数*/ printf("欢迎下次使用!"); /* 先去实现他的基本功能 a.增加功能 按照下标 (这里面的元素是可以重复的)(二笔了.说错了 咱们全部按照JAVA中的Arraylist去实现 查看下api) boolean add(E e) 将指定的元素添加到此列表的尾部。 void add(int index, E element) 将指定的元素插入此列表中的指定位置。 先来实现这两个功能 b.删除功能 删除下标 c.修改功能 d.查找功能 */ /* 第一步:我们先去考虑 先去测量 这个结构的长度 @@@@1 */ //我就是想看一下我成功了没有! /* 一个比较大的疑问 是不是我们全局操作的就是这一个对象*/ /* 下面这个函数为 测试 添加的数据是否成功的 以及再写一个方法,用来遍历我们的数据 */ return 0;}
阅读全文
1 0
- JAVA中ArrayList的底层基本实现
- Java ArrayList的底层实现
- ArrayList底层实现(JAVA)
- ArrayList的底层实现原理
- java中ArrayList的实现
- java类库ArrayList的基本实现
- java学习之旅59--模拟ArrayList容器的底层实现_JDK源码分析ArrayList
- Java中ArrayList的基本用法
- ArrayList和LinkedList底层实现的区别
- ArrayList,Queue,TreeSet,HashMap的底层实现
- 手动实现简单的ArrayList底层
- ArrayList和LinkedList底层实现的区别
- ArrayList、LinkedList、HashMap的底层实现
- ArrayList和LinkedList底层实现的区别
- Java 的 ArrayList 的底层数据结构
- 自己实现一个ArrayList,模仿ArrayList类的底层结构
- 模拟ArrayList底层实现
- ArrayList底层实现
- 路径
- HDU6150 Vertex Cover
- ORACLE10G+asm+RAC集群(linux)
- 笔面试题相关知识点整理(一)--隐式类型转换
- Linux命令英文全称——有助于记忆
- JAVA中ArrayList的底层基本实现
- Qemu运行Linux0.01
- linux学习笔记
- 协方差矩阵
- cropper.js 实现裁剪图片并上传(PC端)
- Android中的Apk的加固(加壳)原理解析和实现
- 暑假集训日记--8.19--树状数组
- [Go]程序结构——作用域
- for循环的一个BUG分享,希望新手小伙伴来看看