在尝试使用链接法编写一个散列表时遇到一个很大的问题
JAVA没有链表和指针(lll¬ω¬)
忽然想起了之前学习过的在没有指针的语言中实现链表的方法,试着实现了以下
代码如下
因为这里需要多链表存入Array里,因此这里新建一个类用于存储链表信息
public class LinkList {
/*
* 链表数值说明:
* -1:该key为空
* -2:该key被删除过
*/
//主键
public int[] Key;
//前驱
public int[] pre;
//后驱
public int[] next;
//这里不提供Get Set方法,在使用链表时切记先调用initLinkList进行初始化
//由于数组长度不可变,因此初始化时需要传入长度
public void initLinkList(int Length) {
this.Key = new int[Length];
this.pre = new int[Length];
this.next = new int[Length];
for(int i=0;i<Length;i++) {
this.Key[i] = -1;
this.pre[i] = -1;
this.next[i] = -1;
}
}
}
//由于数组长度不可变,因此数组大小设置大一些以保证拥有足够的空间
//注意,一旦删除了某个元素那么该元素所在的位置便改为-2
//链表插入操作
public int linkedListInsertion(int info,LinkList data) {
//由于实际过程中并不会有太多冲突,因此采用线性的探查方法可以减少代码的复杂度
int index = -1;
for (int i = 0; i < data.Key.length; i++) {
if (data.Key[i] == -1 || data.Key[i] == -2) {
if (data.Key[i] == -1) {
//设置前驱
if (i != 0) {
data.pre[i] = i-1;
}else {
//表头指向表尾
data.pre[i] = data.Key.length - 1;
}
//设置后驱动
if (i != data.Key.length - 1) {
data.next[i] = i+1;
}else {
//表尾指向表头
data.next[i] = 0;
}
index = i;
}else {
//删除时仅对i的上一个后驱及下一个前驱进行更改,i的前后驱未变,因此无需更改
data.next[i - 1] = i;
data.pre[i + 1] = i;
}
data.Key[i] = info;
break;
}
}
return index;
}
//搜索操作
public int[] searchInfo(int Info,LinkList data) {
ArrayList<Integer> resultArray = new ArrayList<Integer>();
for(int i = 0;i < data.Key.length;i++) {
if (Info == data.Key[i]) {
resultArray.add(i);
}
}
int[] resultIndex = new int[resultArray.size()];
if (resultArray.size() == 0) {
int[] nullResult = new int[1];
nullResult[0] = -1;
return nullResult;
}else {
for(int z = 0;z<resultArray.size();z++) {
resultIndex[z] = resultArray.get(z);
}
return resultIndex;
}
}
//获取前驱
public int getPre(int index,LinkList data) {
if (index > 0 && index < data.Key.length) {
return data.pre[index];
}else {
return -1;
}
}
//获取后驱
public int getNext(int index,LinkList data) {
if (index > 0 && index < data.Key.length) {
return data.next[index];
}else {
return -1;
}
}
//下面两个方法用于手动设置表头表尾
public Boolean setPre(int KeyIndex,int PreIndex,LinkList data) {
if (PreIndex > data.Key.length || PreIndex < 0) return false;
if (KeyIndex > data.Key.length || KeyIndex < 0) return false;
data.pre[KeyIndex] = PreIndex;
return true;
}
public boolean setNext(int KeyIndex,int NextIndex,LinkList data) {
if (NextIndex > data.Key.length || NextIndex < 0) return false;
if (KeyIndex > data.Key.length || KeyIndex < 0) return false;
data.next[KeyIndex] = NextIndex;
return true;
}
//======================================
//删除Key
public boolean deleteList(int keyIndex,LinkList data) {
if (keyIndex > data.Key.length || keyIndex < 0) return false;
data.next[keyIndex - 1] = keyIndex + 1;
data.pre[keyIndex + 1] = keyIndex - 1;
data.Key[keyIndex] = -2;
return true;
}
测试结果如下:
=进行初始赋值=
9 0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 0
=进行删除操作=
9 0 1 2 2 4 5 6 7 8
0 1 2 -2 4 5 6 7 8 9
1 2 4 4 5 6 7 8 9 0
=进行插入操作=
9 0 1 2 3 4 5 6 7 8
0 1 2 19 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 0
注意!!!!
这里仅仅进行了最基本的测试,并不保证代码的可靠性,仅仅用于学习了解一种在未提供链表的语言中实现链表的方法