链表(上)
链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。
相对于数组来讲,链表不需要预先知道数据的大小,它更灵活,可以充分利用计算机的内存空间。缺点是不能像数组一样随机读取数据,而且空间花销也比较大。常见链表有以下几种:
单向链表
单链表(即单向链表)是最简单的链表结构。一个单链表的节点 (Node) 分为两个部分,第一个部分 (data) 是节点本身的数据,另一个部分 (next) 是指向下一个节点的指针。
来个代码看看:
package mylink;
public class MyLink<T> {
private class ListNode{
private T val;
private ListNode next; //默认为 null
ListNode(T val){
this.val = val;
}
}
private ListNode first = null;
public void insertFirst(T val){ //头插法
ListNode data = new ListNode(val);
data.next = first;
first = data;
}
public Object deleteFirst() throws Exception{
if(first == null)
throw new Exception("empty!");
ListNode temp = first;
first = first.next;
return temp.val;
}
public Object find(Object val) throws Exception{
if(first == null)
throw new Exception("LinkedList is empty!");
ListNode cur = first;
while(cur != null){
if(cur.val.equals(val)){
return cur.val;
}
cur = cur.next;
}
return null;
}
public void remove(Object val) throws Exception{
if(first == null)
throw new Exception("LinkedList is empty!");
if(first.val.equals(val)){
first = first.next;
}else{
ListNode pre = first;
ListNode cur = first.next;
while(cur != null){
if(cur.val.equals(val)){
pre.next = cur.next;
}
pre = cur;
cur = cur.next;
}
}
}
public boolean isEmpty(){
return (first == null);
}
public void display(){
if(first == null)
System.out.println("empty");
ListNode cur = first;
while(cur != null){
System.out.print(cur.val.toString() + " -> ");
cur = cur.next;
}
System.out.print("\n");
}
public static void main(String[] args) throws Exception {
MyLink<Integer> list = new MyLink<Integer>();
list.insertFirst(4);
list.insertFirst(3);
list.insertFirst(2);
list.insertFirst(1);
list.display();
list.deleteFirst();
list.display();
list.remove(3);
list.display();
System.out.println(list.find(1));
System.out.println(list.find(4));
}
}
运行结果截图:
其实就是一个链表类里面有一个节点类,节点类的核心代码如下:
public class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
双端链表
就是有头有尾的单向链表,代码如下:
package mylink;
public class MyLink<T> {
private class ListNode{
private T val;
private ListNode next;
ListNode(T val){
this.val = val;
}
}
private ListNode first = null;
private ListNode last = null;
public void insertFirst(T val){
ListNode data = new ListNode(val);
if(first == null)
last = data;
data.next = first;
first = data;
}
public void insertLast(T val){
ListNode data = new ListNode(val);
if(first == null){
first = data;
}else{
last.next = data;
}
last = data;
}
public Object deleteFirst() throws Exception{
if(first == null)
throw new Exception("empty");
ListNode temp = first;
if(first.next == null)
last = null;
first = first.next;
return temp.val;
}
public void deleteLast() throws Exception{
if(first == null)
throw new Exception("empty");
if(first.next == null){
first = null;
last = null;
}else{
ListNode temp = first;
while(temp.next != null){
if(temp.next == last){
last = temp;
last.next = null;
break;
}
temp = temp.next;
}
}
}
public void display(){
if(first == null)
System.out.println("empty");
ListNode cur = first;
while(cur != null){
System.out.print(cur.val.toString() + " -> ");
cur = cur.next;
}
System.out.print("\n");
}
public static void main(String[] args) throws Exception {
MyLink<Integer> list = new MyLink<Integer>();
list.insertFirst(2);
list.insertFirst(1);
list.display();
list.insertLast(3);
list.display();
list.deleteFirst();
list.display();
list.deleteLast();
list.display();
}
}
运行结果截图: