1.要实现的功能
1. 可以任意添加任意类型的数据 void add(Object obj)
2. 可以记录当前数据的个数 int size()
3. 可以打印当前数据结构的对象 toString(),格式如下:[值1,值2.。。。。]
4. 查询指定下标的元素 Object searchByIndex(int index)
5. 查询指定的元素第一次出现的位置 int searchByElement(Object ele);
为了更快实现后面的功能我们需要先实现:根据下标查询当前的节点对象 Node searchNodeByIndex(int index)
6. 修改指定下标处的元素 void updateByIndex(int index,Object obj)
7. 删除指定下标处的元素,返回删除的元素 Object deleteByIndex(int index)
8. 删除的首次出现的指定元素 void deleteByElement(Object ele)
9. 插入指定下标处一个指定元素 void insertByIndex(int index,Object obj)
11.将对象中所有元素清空 void clear();
2.代码实现
package homework;
public class LinkedListDemo {
private Node first;
private int size;
/**
* 清空链表
*/
public void clear(){
first=null;
size=0;
}
/**
* 插入指定下标处一个指定元素
* @param index
* @param obj
*/
public void insertByIndex(int index,Object obj){
checkIndex(index);
Node myNode=new Node(obj);
if(index==0){
myNode.next=first;
first=myNode;
}else{
Node preNode=searchNodeByIndex(index-1); //只需要找到之前的元素
Node temp=preNode.next; //因为之前的是指向之后
preNode.next=myNode;
myNode.next=temp;
}
size++; //当前的长度+1
}
/**
* 删除的首次出现的指定元素
* @param ele
*/
public void deleteByElement(Object ele){
deleteByIndex(searchByElement(ele)); //直接调用我们之前写好的方法
}
/**
* 删除指定下标处的元素,返回删除的元素
* @param index
* @return
*/
public Object deleteByIndex(int index){
Object res=searchByIndex(index); //必须先保存被删除的元素,否者发生空指针异常
checkIndex(index);
if(index==0){
this.first=this.first.next;
}else{
Node currentNode=searchNodeByIndex(index);
Node preNode=searchNodeByIndex(index-1);
preNode.next=currentNode.next;
}
size--;
return res;
}
/**
* 修改指定下标处的元素
* @param index
* @param obj
*/
public void updateByIndex(int index,Object obj){
searchNodeByIndex(index).value=obj;
}
/**
* 根据下标查询当前的节点对象
* @param index
* @return
*/
public Node searchNodeByIndex(int index){
checkIndex(index);
Node temp=first;
for(int i=0;i<index;i++){
temp=temp.next;
}
return temp;
}
/**
*查询指定的元素第一次出现的位置
* @param ele
* @return
*/
public int searchByElement(Object ele){
int index=-1;
int counter=0;
Node temp=first;
while(temp!=null){
if(ele==null){
index= temp.value==null?counter:index;
}else{
index= ele.equals(temp.value)?counter:index;
}
temp=temp.next;
counter++;
}
return index;
}
/**
* 查询指定下标的元素
* @param index
* @return
*/
public Object searchByIndex(int index){
int i=-1;
Node temp=first;
while( ++i<index){
temp=temp.next;
}
return temp.value;
}
/**
* 返回当前链表的长度
* @return
*/
public int size(){
return this.size;
}
/**
* 添加任意类型的数据
* @param obj
*/
public void add(Object obj){
if(first==null){
first=new Node(obj);
}else{
Node temp=first;
while(temp.next!=null){ //这不能用temp来遍历,因下面这一行会把temp清空
temp=temp.next;
}
temp.next=new Node(obj); //如果循环用temp这里也用temp那么么这的temp就会是null附上一个新的值也就不会连接到first
}
this.size++;
}
@Override
public String toString() {
Node temp=first;
StringBuilder sb=new StringBuilder("[");
if(size!=0){
while(temp!=null){
sb.append(temp.value).append(",");
temp=temp.next;
}
}
return sb.append("]").toString().replaceAll(",(?=\\]$)", "");
}
/**
* 检查数组下标是否越界
* @return
*/
private void checkIndex(int index){
if(index<0 || index>=size){
throw new ArrayException("你是zz吗,数组越界了");
}
}
/**
* 节点类,因为我们只是需要本类使用,所有直接放在了本类中,
*
*/
class Node{
public Object value;
public Node next;
Node(Object value){ //通过有参构造来构造Node对象
this.value=value;
}
}
}