ArrayList,LinkedList,HashTable三者是JAVA中的三种常见的数据结构,当然它们的性能有不同的差异,比如数据查找速度,增加或删除数据的速度,内存空间占用等等,这将在下篇博客中体现,这篇博客只是大致应用数据结构知识来自己实现三种数据结构的基本功能,包含一些简单的增查改删功能。
ArrayList:
public class ArrayList {
private int counts; //数组实际填充大小
private int stepcount; //数组将溢出时的扩充步长
Object[] data =new Object[10]; //默认数组长度为10
//无参的构造方法,默认扩充步长为100
public ArrayList(){
stepcount=100;
}
//带初始数组长度与扩充步长的构造方法
public ArrayList(int initlen,int stepcount){
data=new Object[initlen];
this.stepcount=stepcount;
}
//给数组添加新数据
public void add(Object obj){
if(counts>=data.length){ //判断有无溢出,溢出则增加数组长度stepcount,并将原数组数据放入新数组
Object[] data2=new Object[data.length+stepcount];
for(int i=0;i<data.length;i++){
data2[i]=data[i];
}
data=data2;
}
data[counts++]=obj;
}
//获得指定数组位置的内容
public Object get(int index){
if(index<0||index>data.length){
System.out.println("超出数组限定范围");
return null;
}
return data[index];
};
//删除指定位置的元素
public void remove(int index){
Object[] data2 = new Object[data.length-1];
for (int i=0;i<index;i++){
data2[i]=data[i];
}
for (int i=index+1;i<data.length;i++){
data2[i-1]=data[i];
}
data=data2;
Object obj =data[index];
}
//获得数组大小
public int size(){
return counts;
}
//在指定位置插入元素
public void insert(Object obj,int index){
Object[] data2 =new Object[data.length+1]; //新建一数组才可从数组中间插入,此时新数组长度需至少加一
for(int i=0;i<index;i++){
data2[i]=data[i];
}
data2[index]=obj;
for(int i=index+1;i<data2.length;i++){
data2[i]=data[i-1];
}
data=data2;
}
}
LinkedList:
public class MyLinkList implements List {
//声明根节点
private Node root=null
private Node tail,tempt;
private int total;
//给链表添加元素
public void add(Object obj) {
Node newnode =new Node();
if (root==null){
newnode.data=obj;
root=newnode;
tail=newnode;
}
else{
tail.next=newnode;
newnode.data=obj;
tail=newnode;
}
total++;
}
//获取链表指定位置元素(为便于习惯,默认从一开始)
public Object get(int index) {
if(index==0){
return null;
}
if(index-1==0){
return root.data;
}
else {
tempt=root;
for(int i=1;i<index;i++){
tempt=tempt.next;
}
return tempt.data;
}
}
//删除某指定链表元素
public void remove(int index) {
if(index-1==0){
root=root.next;
}
else {
tempt=root;
for(int i=1;i<index-1;i++){
tempt=tempt.next;
}
tempt.next=tempt.next.next;
}
total--;
}
//获得链表的大小
public int size() {
return total;
}
//给链表指定位置插入某元素
public void insert(Object obj, int index) {
Node insertNode =new Node();
insertNode.data=obj;
if(index-1==0){
insertNode.next=root;
root=insertNode;
}
else {
tempt=root;
for(int i=1;i<index-1;i++){
tempt=tempt.next;
}
insertNode.next=tempt.next;
tempt.next=insertNode;
}
total++;
}
//该链表内部类实现对Node的定义
class Node{
Object data;
Node next;
Node(Node next,Object data){
this.next=next;
this.data=data;
}
}
}
HashTable:
public class MyHashTable{
private Object[] saveKey; //存关键字的数组
private int size; //数组大小
//无参的构造函数
public MyHashTable(){
saveKey= new Object[16]; //默认数组长度是16
size = 0;
}
//带参数的构造函数
public MyHashTable(int arraylenght,int size){
saveKey=new Object[arraylenght];
this.size=size;
}
//哈希函数
public int hash(Object obj){
return Math.abs(obj.hashCode())%saveKey.length;
}
//处理冲突的哈希函数
public int hashForCollision(Object obj){
int newhash = Math.abs(obj.hashCode())%(saveKey.length-1);//这里调用里JDK里自有的hashcode方法后实现映射
if(newhash%2==0){
return newhash + 1;
}
return newhash;
}
//判断哈希表里面是否已有某对象
public boolean contains(Object obj){
int i = hash(obj);
while (saveKey[i] != null){
if(saveKey[i].equals(obj)){
return true;
}
i = (i + hashForCollision(obj))%saveKey.length;
}
return false;
}
//添加新元素
public void add(Object obj){
//先判断是否需要扩容,若已有数据占原数组一半,则扩容
if(size>=saveKey.length/2){
this.rehash();
}
int i = hash(obj);//获取其哈希值
while(saveKey[i] != null){
if(obj.equals(saveKey[i])){
return;
} //判断该索引处是否已占用,若占用则调用hashforcollision生成新地址
i = (i + hashForCollision(obj))%saveKey.length;
}
saveKey[i] = obj;
size ++;
}
//扩大哈希表为原表的四倍,并把原来的哈希表添加到新表中
public void rehash(){
MyHashTable ht = new MyHashTable();
ht.saveKey = new String[this.saveKey.length * 4];
for(int i = 0; i < this.saveKey.length; i ++){
if((this.saveKey[i] != null)){
ht.add(this.saveKey[i]);
}
}
this.saveKey = ht.saveKey;
this.size = ht.size;
}
//删除某个元素
public void remove(Object obj){
if(this.contains(obj)){
int i = this.getIndex(obj);
this.saveKey[i] = null;
}
}
//得到某对象在哈希表中的位置
public int getIndex(Object obj){
int i = this.hash(obj);
while(this.saveKey[i] != null){
if(this.saveKey[i].equals(obj)){
return i;
}
i = (i + this.hashForCollision(obj))%this.saveKey.length;
}
return -1;
}
//获取哈希表中某元素
public Object get(Object obj){
if(this.contains(obj)){
int i = this.getIndex(obj);
return saveKey[i] ;
}
return null;
}
//输出哈希表中所有元素
public void print(){
for(int i = 0; i < saveKey.length; i ++){
System.out.println(i+":"+saveKey[i]);
}
}
//哈希表存储元素的个数
public int size(){
return this.size;
}
//哈希表的长度
public int length(){
return this.saveKey.length;
}
以上三个实现的数据结构都经过测试,能实现其所写功能。