Java中已经定义好了一个长度可变数组:ArrayList
数组的特点:内存地址连续
优点:数据是存放在一个连续的内存地址上,查找效率比较高
缺点:在改变数据个数的时候[增加,插入,删除]效率比较低
链式列表:[链表] 数据在内存中可以在任意位置,通过引用来关联数据
1.MyArray 数组
2.Main主函数实现
3.双向链表
4、主函数Main实现
数组的特点:内存地址连续
优点:数据是存放在一个连续的内存地址上,查找效率比较高
缺点:在改变数据个数的时候[增加,插入,删除]效率比较低
链式列表:[链表] 数据在内存中可以在任意位置,通过引用来关联数据
1.MyArray 数组
package com.newer.cjl.api;
/**
* 自定义长度可变的数组[泛型]
*
* @author Administrator
*
*/
public class MyArray<E> {
// 定义一个长度为0的初始数组
private Object[] src = new Object[0];
/**
* 存放数据
*
* @param s
* 要存放的数据
*/
public void add(E s) {
// 定义一个新数组长度是源数组长度+1
Object[] dest = new Object[src.length + 1];
// 将原数组的数据拷贝到新数组中
System.arraycopy(src, 0, dest, 0, src.length);
// 将新数据放到新数组的最后一个位置
dest[dest.length - 1] = s;
// 将原数组指向新数组
src = dest;
}
/**
* 取出数据
*
* @param index
* 要取出的数据的下标
*/
public E get(int index) {
Object s = src[index];
return (E)s;
}
/**
* 根据下标删除数据
*
* @param index
* 要删除的数据的下标
*/
public void delete(int index) {
Object[] dest = new Object[src.length-1];
//将下标小于index的拷贝到新数组对应的下标位置
System.arraycopy(src, 0, dest, 0, index);
//将下标大于index的拷贝到新数组下标的位置为原数组的下标位置-1
System.arraycopy(src, index+1, dest, index, src.length-index-1);
//将src指向新数组
src=dest;
}
/**
* 删除指定的数据
*
* @param s
* 要删除的数据,如果有重复的数据,就删除下标最小的
*/
public void delete(E s) {
int t=-1;
for(int i=0;i<src.length;i++){
if(src[i].equals(s)){
t=i;
break;
}
}
//如果s在数组中出现过,t一定会>=0
if(t>=0){
delete(t);
}
}
/**
* 将数据插入到指定位置
* @param index 要插入的位置
* @param s 要插入的数据
*/
public void insert(int index,E s){
Object[] dest = new Object[src.length+1];
//将新数据放到新数组的指定位置
dest[index]=s;
//将下标小于index的数据拷贝到新数组对应的下标位置
System.arraycopy(src, 0, dest, 0, index);
//将下标>=index的数据宝贝到新数组下标+1的位置
System.arraycopy(src, index, dest, index+1, src.length-index);
src=dest;
}
/**
* 修改数据
*
* @param index
* 要修改的数据的下标
* @param s
* 修改后的数据
*/
public void update(int index, E s) {
src[index] = s;
}
/**
* 获得数据个数
*/
public int size() {
return src.length;
}
}
2.Main主函数实现
package com.newer.cjl.api;
import java.util.ArrayList;
/**
* 自定义长度可变数组的测试类
*
* @author Administrator
*
*/
public class Main {
public static void main(String[] args) {
// // 创建数组对象
// MyArray<String> arr = new MyArray<String>();
// // 增加数据
// arr.add("AA");
// arr.add("BB");
// arr.add("CC");
// arr.add("DD");
// arr.add("EE");
// arr.add("FF");
//
//
// arr.insert(5, "新来的");
//
// // 取出数据
// for (int i = 0; i < arr.size(); i++) {
// String s = arr.get(i);
// System.out.println(s);
// }
ArrayList<Integer> arr = new ArrayList<Integer>();
arr.add(100);
arr.add(200);
arr.add(300);
for(int i=0;i<arr.size();i++){
int t = arr.get(i);
System.out.println(t);
}
}
}
3.双向链表
package com.newer.cjl.api;
/**
* 自定义链表类【双向链表】
*
* @author Administrator
*
*/
public class MyLinkList<E> {
// 初始状态下,链表没有任何结点,头结点为null,尾结点为null
private Node<E> head = null;
private Node<E> last = null;
private int num = 0;// 数据个数
// 增加数据
public void add(E e) {
// 根据数据创建结点对象
Node<E> node = new Node<E>(e);
// 如果链表中已经有结点,就将node作为last的下一个结点
if (last != null) {
last.next = node;
node.front = last;
last = node;
} else {
// 如果链表中还没有结点,node就是第一个结点
// 既是头结点,又是尾结点
head = node;
last = node;
}
num++;
}
public void insert(int index, E e) {
// 创建新结点
Node<E> node = new Node<E>(e);
// 找到index位置的结点
Node<E> n1 = getNode(index);
// 找到n1的前一个结点
Node<E> n2 = n1.front;
n2.next = node;
node.front = n2;
node.next = n1;
n1.front = node;
num++;
}
public void delete(int index) {
}
public void delete(E e) {
}
public void update(int index, E e) {
Node<E> n1 = getNode(index);
n1.data = e;
}
public E get(int index) {
Node<E> node = getNode(index);
return node.data;
}
//根据内容确定下标
private int getIndex(E e){
int index=-1;
Node<E> n = head;
while(n!=null){
index++;
if(n.data.equals(e)){
break;
}
n=n.next;
}
return index;
}
public int getIndex2(E e){
for(int i=0;i<num;i++){
E e2 = get(i);
if(e2.equals(e)){
return i;
}
}
return -1;
}
//根据下标确定结点
private Node<E> getNode(int index) {
int t = -1;
if (index >= 0 && index < num) {
Node<E> n = head;
while (n != null) {
t++;
if (t == index) {
break;
}
n = n.next;
}
return n;
} else {
// 抛出异常
throw new IndexOutOfBoundsException("下标超出边界!index:" + index
+ ",size:" + num);
}
}
public int size() {
return num;
}
}
// 内部的结点类,主要为MyLinkList类服务
class Node<E> {
// 结点的数据
E data;
// 对下一个结点的引用
Node<E> next;
// 对前一个结点的引用
Node<E> front;
// 创建结点对象的时候必须指定数据
public Node(E e) {
data = e;
}
}
4、主函数Main实现
package com.newer.cjl.api;
public class Main4 {
public static void main(String[] args) {
MyLinkList<String> list = new MyLinkList<String>();
list.add("AA");
list.add("BB");
list.add("CC");
list.add("BB");
list.add("DD");
// //测试add方法是否正确
// System.out.println(list.last.data);
// Node<String> node = list.last.front;
// while(node!=null){
// System.out.println(node.data);
// node = node.front;
//
// }
// list.insert(2, "EE");
// list.update(3, "FF");
//
// for (int i = 0; i < list.size(); i++) {
// String s = list.get(i);
// System.out.println(s);
// }
int t = list.getIndex2("BB");
System.out.println(t);
}
}