java中的LinkedList本质上是一条双向链表,因为在学C的数据结构的时候没有实现过双向链表,借此机会来理解java中的LinkedList深层次的实现。这里本人手动实现的LinkedList中没有头节点,如果有需要,可以自己手动添加。
目录
1. 节点的结构定义
2.用尾插法增加一个节点
3.改写toString()方法
4.返回特定下标的节点
5.删除一个节点
6.插入一个节点
7.取得指定下表的节点的内容
手动分割线 -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MyLinkedList类的属性和方法:
public class MyLinkedList {
private Node first;//第一个节点
private Node last;//最后一个节点
private int size;//节点的个数
public void linkListAdd(Object obj);
public void linkListRemove(int index);
public void linkListInsert(Object obj , int index);
public String toString();
public Node getNode(int index);
public Object get(int index);
}
1. 节点的结构定义
public class Node{
Node previous;
Node next;
Object element;
public Node(Object obj) {
this.element = obj;
}
}
2.用尾插法增加一个节点
public void linkListAdd(Object obj) {
size++;
Node node = new Node(obj);
if(first==null) {
first = node;
last = node;
}else {
last.next = node;
node.previous = last;
last = node;
}
}
3.改写toString()方法
public String toString() {
Node temp = first;
while(temp!=null) {
System.out.print(temp.element);
temp = temp.next;
}
return "\n";
}
4.返回特定下标的节点
public Node getNode(int index) {
if(index<0||index>size-1) {
throw new RuntimeException("索引不合法:"+index);
}
Node temp=null;
if(index<=(size>>1)) {//位运算比除法的效率要高
temp = first;
for(int i=0 ; i<index ; i++) {
temp = temp.next;
}
}else {
temp = last;
for(int i=size-1 ; i>index ; i--) {
temp = temp.previous;
}
}
return temp;
}
5.删除一个节点
public void linkListRemove(int index) {
if(index==0) {
first=first.next;
first.previous=null;
}else if(index==size-1){
last=last.previous;
last.next=null;
}else {
Node temp=getNode(index);
temp.previous.next=temp.next;
temp.next.previous=temp.previous;
temp.next=temp.previous=null;
}
size--;
}
6.插入一个节点
public void linkListInsert(Object obj , int index) {
Node node = new Node(obj);
if(index==0) {
first.previous=node;
node.next=first;
first=node;
}else if(index==size) {
last.next=node;
node.previous=last;
last=node;
}else {
Node temp=getNode(index);
node.next=temp;
node.previous=temp.previous;
temp.previous.next=node;
temp.previous=node;
}
size++;
}
从删除和插入的操作我们可以看出:没有头节点的链表在进行删除(插入)时还要判断要删除(插入)的是否为第一个或者最后一个节点,而有头节点就不需要这些判断。
7.取得指定下表的节点的内容
public Object get(int index) {
Node temp = getNode(index);
return temp==null?null:temp.element;
}
源代码:
public class MyLinkList {
private Node first;
private Node last;
private int size;
//用尾插法增加一个节点
public void linkListAdd(Object obj) {
size++;
Node node = new Node(obj);
if(first==null) {
first = node;
last = node;
}else {
last.next = node;
node.previous = last;
last = node;
}
}
//删除一个节点
public void linkListRemove(int index) {
if(index==0) {
first=first.next;
first.previous=null;
}else if(index==size-1){
last=last.previous;
last.next=null;
}else {
Node temp=getNode(index);
temp.previous.next=temp.next;
temp.next.previous=temp.previous;
temp.next=temp.previous=null;
}
size--;
}
//插入一个节点
public void linkListInsert(Object obj , int index) {
Node node = new Node(obj);
if(index==0) {
first.previous=node;
node.next=first;
first=node;
}else if(index==size) {
last.next=node;
node.previous=last;
last=node;
}else {
Node temp=getNode(index);
node.next=temp;
node.previous=temp.previous;
temp.previous.next=node;
temp.previous=node;
}
size++;
}
//打印链表,改写toString方法
public String toString() {
Node temp = first;
while(temp!=null) {
System.out.print(temp.element);
temp = temp.next;
}
return "\n";
}
//返回特定下标的节点
public Node getNode(int index) {
if(index<0||index>size-1) {
throw new RuntimeException("索引不合法:"+index);
}
Node temp=null;
if(index<=(size>>1)) {
temp = first;
for(int i=0 ; i<index ; i++) {
temp = temp.next;
}
}else {
temp = last;
for(int i=size-1 ; i>index ; i--) {
temp = temp.previous;
}
}
return temp;
}
//取得指定下表的节点的内容
public Object get(int index) {
Node temp = getNode(index);
return temp==null?null:temp.element;
}
public static void main(String[] args) {
MyLinkList linklist = new MyLinkList();
linklist.linkListAdd("a");
linklist.linkListAdd("b");
linklist.linkListAdd("c");
linklist.linkListAdd("d");
linklist.linkListAdd("e");
System.out.print(linklist);
System.out.println("链表的长度为:"+linklist.size);
System.out.println("从链表中取得的元素为:"+linklist.get(4));
linklist.linkListRemove(3);
System.out.print(linklist);
linklist.linkListInsert("f", 4);
System.out.println(linklist);
}
}