链表概念
链表的物理存储结构是非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接的次序实现的.
链表的数据结构
链表由一系列结点组成,每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。链表在插入的时候速度较快,可以达到O(1)的复杂度,但是查找操作较慢,需要O(n)的时间,线性表和顺序表查找操作的时间复杂度分别是O(logn)和O(1)。
代码如下:
public class Node {
//数据域
Object value;
Node next;
public Node(Object value,Node next) {
this.value=value;
this.next=next;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value=value;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next=next;
}
}
public class CLinkedList {
Node root;
int size;
Node last;//表示链表尾节点
}
插入操作:
尾插
//尾插(不使用last)
public void add(Object e) {
if(root==null) {
root=new Node(e,null);
size++;
return;
}
Node temp=root;
while(temp.next!=null) {
temp=temp.next;
}
temp.next=new Node(e,null);
size++;
}
头插
//头插
public void addFirst(Object e) {
if(root==null) {
root=new Node(e,null);
last = root;
size++;
return;
}
root=new Node(e,root);
size++;
}
利用尾节点last尾插法插入结点
public void addLast(Object e){
if(root == null){
root = new Node (e, null);
last = root;
size++;
}
last.next = new Node (e, null);
last = last.next;
size++;
}
下标检查
private boolean checkIndex(int index) {
if(index<0||index>=size) {
throw new ArrayIndexOutOfBoundsException("index必须大于0小于"+size);
}
return true;
}
指定位置插入结点
//在指定位置插入元素
public void add(int index,Object e){
Node temp=root;
checkIndex(index);
for(int i=0;i<index-1;i++) {
temp=temp.next;
}
Node node=new Node(e,temp.next);
temp.next=node;
size++;
}
在指定结点前添加结点
//找到e1元素,在e1前插入e2
public void add(Object e1,Object e2){
Node temp=root;
if(temp.value==e1) {
Node node=new Node(e2,temp);
root=node;
size++;
return;
}
while(temp.next!=null) {
if(temp.next.value==e1) {
Node node=new Node(e2,temp.next);
temp.next=node;
size++;
return;
}
temp=temp.next;
}
System.out.println("找不到"+e1);
}
查找操作:
指定位置查找结点值
//获取指定位置结点值
public Object get(int index){
Node temp=root;
checkIndex(index);
//找到索引为index的链表结点
for(int i=0;i<index;i++) {
temp=temp.next;
}
Object e=temp.value;
return e;
}
查找结点所在位置
//返回索引值
public int[] get(Object e){
Node temp=root;
int index=0;
int[] getIndex=new int[size];
for(int i=0;i<size;i++) {
if(temp.value==e) {
getIndex[index++]=i;
}
temp=temp.next;
}
if (index==0) {
System.out.println("没有该元素!");
return new int[] {};
}
int[] mannyIndex=new int[index];//定义一个新数组
mannyIndex=java.util.Arrays.copyOf(getIndex,index);//将原来数组截断,只把下标保存到新数组
getIndex=null;//将原数组删除
return mannyIndex;
}
删除操作:
删除指定位置结点
public void remove(int index){
Node temp=root;
Node pre=temp;
checkIndex(index);
//找到索引为index的链表结点
for(int i=0;i<index;i++) {
pre=temp;
temp=temp.next;
}
if(temp.next!=null) {
if(temp==root) {
root=root.next;
size--;
}else {
pre.next=pre.next.next;
size--;
}
}else {
if(temp==root) {
root=null;
size--;
}else
{pre.next=null;
size--;}
}
}
先查找结点比对结点值再删除
public void removeAll(Object e){
int[] getIndex=get(e);
int i=0;
//找不到
if(getIndex.length==0) {
return;
}
//
for(int j=0;j<getIndex.length;j++) {
remove(getIndex[j]-i);
i++;
}
}
测试:
public static void main(String[] args){
CLinkedList clink =new CLinkedList ();
//添加元素
clink.addFirst(3);
clink.addFirst(6);
clink.addFirst(3);
clink.addFirst(4);
clink.addFirst(3);
//在e1前添加e2
clink.add((Object)6, (Object)4);
//
// Object e=3;
// System.out.print(e+"的索引为");
// int[] index=clink.get(e);
// for(int j=0;j<index.length;j++) {
// System.out.print(index[j]+" ");
// }
// System.out.println();
//
clink.removeAll(3);
// clink.remove(0);
//获取元素
// System.out.print("当前索引的元素值为:"+ clink.get(1));
//打印链表元素和size
Node temp=clink.root;
System.out.print("当前链表为");
while(temp!=null) {
System.out.print(temp.value+" ");
temp=temp.next;
}
System.out.println();
System.out.print("当前size为"+clink.size);
}