单链表与双向链表的Java实现
2012-12-09 20:26
513 查看
链表是一种物理存储单元上非连续、非顺序的存储结构。链表的机制灵活,它可以替代数组成为栈、队列的基础存储结构。链表比数组来说,没有大小限制,插入删除不基本需要移动元素。
链表的概念,就像有一群人,其中一个人举起一面旗子。而其他的人必须抓住另一个的后背,而且只能抓住一个。这样,所有的人就形成了一条人链,这个结构就是链表,而人就是链节点。
首先,我们先将链节点的代码写上:
public class Link
{
//id,数据,下一个
public int id;
public int data;
public Link next;
public Link(int id,int data)
{
this.id = id;
this.data = data;
this.next = null;
}
//显示数据
public String displayLink()
{
return "<ID:" + id +",Data:" + data + ",Next:"+ (next == null?"null":next.id) + ">";
}
}
然后,构建链表,他包括插入、删除、判空、显示、查找等方法,其代码如下:
public class LinkedList
{
//链表头
private Link first;
public LinkedList()
{
first = null;
}
//显示整个链表
public void displayLinkedList()
{
Link current =first;
StringBuffer sb = new StringBuffer("");
if(current == null )
sb.append("链表为空。");
else
sb.append("链表如下:\n");
while(current != null)
{
sb.append(current.displayLink()+"\n");
current = current.next;
}
System.out.println(sb.toString());
}
//插入
public void insertFrist(int id,int data)
{
Link newLk = new Link(id,data);
newLk.next = first;
first = newLk;
}
//删除
public Link delectFrist()
{
if(!isEmpty())
{
Link tempLk = first;
first = first.next;
return tempLk;
}
else
throw new IndexOutOfBoundsException("链表已空");
}
//判空
public boolean isEmpty()
{
return first == null;
}
//查找特定元素
public Link find(int data)
{
Link current =first;
while(current != null)
{
if(current.data == data)
return current;
current = current.next;
}
return null;
}
//删除特定元素
public Link delete(int data)
{
Link current = first;
Link crtParent = null;
while(current != null)
{
if(current.data == data)
{
if(crtParent == null)
first = first.next;
else
crtParent.next = current.next;
return current;
}
crtParent = current;
current = current.next;
}
return null;
}
public static void main(String[] args) {
LinkedList ll = new LinkedList();
ll.insertFrist(1, 0);
ll.insertFrist(2, 11);
ll.insertFrist(3, 9);
ll.insertFrist(4, 93);
ll.insertFrist(5, 12);
ll.insertFrist(6, 16);
ll.displayLinkedList();
}
}
这是一个单链表类,只能通过next后继遍历元素,大家可以看出,链头插入元素只需要修改next标志位,不需要移动后面的元素,我们测试一下:
链表如下:
<ID:6,Data:16,Next:5>
<ID:5,Data:12,Next:4>
<ID:4,Data:93,Next:3>
<ID:3,Data:9,Next:2>
<ID:2,Data:11,Next:1>
<ID:1,Data:0,Next:null>
另外,如果单链表中各元素都是有序的,那就叫有序链表,我们为其编写一个新的有序插入方法,其代码如下:
将mian方法中的insertFrist修改为insertForSort。测试一下,结果如下:
还有种链表叫双向链表,它的链节点中不仅包括后继next,还包括前继prev,所以他不仅可以从前遍历,还可以从后便遍历,但其代码比单链表的复杂,这里我们将id和data合并成key,链节点代码如下:
双向链表代码如下:
我们来测试一下:
链表的概念,就像有一群人,其中一个人举起一面旗子。而其他的人必须抓住另一个的后背,而且只能抓住一个。这样,所有的人就形成了一条人链,这个结构就是链表,而人就是链节点。
首先,我们先将链节点的代码写上:
public class Link
{
//id,数据,下一个
public int id;
public int data;
public Link next;
public Link(int id,int data)
{
this.id = id;
this.data = data;
this.next = null;
}
//显示数据
public String displayLink()
{
return "<ID:" + id +",Data:" + data + ",Next:"+ (next == null?"null":next.id) + ">";
}
}
然后,构建链表,他包括插入、删除、判空、显示、查找等方法,其代码如下:
public class LinkedList
{
//链表头
private Link first;
public LinkedList()
{
first = null;
}
//显示整个链表
public void displayLinkedList()
{
Link current =first;
StringBuffer sb = new StringBuffer("");
if(current == null )
sb.append("链表为空。");
else
sb.append("链表如下:\n");
while(current != null)
{
sb.append(current.displayLink()+"\n");
current = current.next;
}
System.out.println(sb.toString());
}
//插入
public void insertFrist(int id,int data)
{
Link newLk = new Link(id,data);
newLk.next = first;
first = newLk;
}
//删除
public Link delectFrist()
{
if(!isEmpty())
{
Link tempLk = first;
first = first.next;
return tempLk;
}
else
throw new IndexOutOfBoundsException("链表已空");
}
//判空
public boolean isEmpty()
{
return first == null;
}
//查找特定元素
public Link find(int data)
{
Link current =first;
while(current != null)
{
if(current.data == data)
return current;
current = current.next;
}
return null;
}
//删除特定元素
public Link delete(int data)
{
Link current = first;
Link crtParent = null;
while(current != null)
{
if(current.data == data)
{
if(crtParent == null)
first = first.next;
else
crtParent.next = current.next;
return current;
}
crtParent = current;
current = current.next;
}
return null;
}
public static void main(String[] args) {
LinkedList ll = new LinkedList();
ll.insertFrist(1, 0);
ll.insertFrist(2, 11);
ll.insertFrist(3, 9);
ll.insertFrist(4, 93);
ll.insertFrist(5, 12);
ll.insertFrist(6, 16);
ll.displayLinkedList();
}
}
这是一个单链表类,只能通过next后继遍历元素,大家可以看出,链头插入元素只需要修改next标志位,不需要移动后面的元素,我们测试一下:
链表如下:
<ID:6,Data:16,Next:5>
<ID:5,Data:12,Next:4>
<ID:4,Data:93,Next:3>
<ID:3,Data:9,Next:2>
<ID:2,Data:11,Next:1>
<ID:1,Data:0,Next:null>
另外,如果单链表中各元素都是有序的,那就叫有序链表,我们为其编写一个新的有序插入方法,其代码如下:
//插入有序 public void insertForSort(int id,int data) { Link current = first; Link crtParent = null; Link newLk = new Link(id,data); while(current != null && current.data <= data) { crtParent = current; current = current.next; } if(crtParent == null) first = newLk; else crtParent.next = newLk; newLk.next = current; }
将mian方法中的insertFrist修改为insertForSort。测试一下,结果如下:
链表如下: <ID:1,Data:0,Next:3> <ID:3,Data:9,Next:2> <ID:2,Data:11,Next:5> <ID:5,Data:12,Next:6> <ID:6,Data:16,Next:4> <ID:4,Data:93,Next:null>
还有种链表叫双向链表,它的链节点中不仅包括后继next,还包括前继prev,所以他不仅可以从前遍历,还可以从后便遍历,但其代码比单链表的复杂,这里我们将id和data合并成key,链节点代码如下:
public class DuoLink { //Key,后继,前继 public int key; public DuoLink next; public DuoLink prev; public DuoLink(int key) { this.key = key; this.next = null; this.prev = null; } public String displayLink() { return "<Key:" + key + ",Next:"+(next==null?"null":next.key)+ ",Prev:"+(prev == null?"null":prev.key)+">"; } }
双向链表代码如下:
public class DuoLinkedList { //链表头、链表尾 private DuoLink first; private DuoLink last; public DuoLinkedList(){ first = null; last = null; } //判空 public boolean isEmpty(){ return first == null; } //查找 public DuoLink find(int key) { DuoLink current = first; while(current != null && key != current.key) { current = current.next; } return current; } //表头插入 public void insertFirst(int in) { DuoLink newDL = new DuoLink(in); if(first == null) last = newDL; else { first.prev = newDL; newDL.next = first; } first = newDL; } //表尾插入 public void insertLast(int in) { DuoLink newDL = new DuoLink(in); if(last == null) first = newDL; else { newDL.prev = last; last.next = newDL; } last = newDL; } //在key后插入 public void insertAfter(int key,int in) throws Exception { DuoLink find = find(key);//找到元素 DuoLink newDL = new DuoLink(in); if(find == null) throw new Exception("no find"); else if(find == last) insertLast(in); else { find.next.prev = newDL; newDL.prev = find; newDL.next = find.next; find.next = newDL; } } //删除表头元素 public DuoLink deleteFirst() throws Exception { if(isEmpty()) throw new Exception("空链表"); if(first.next == null) last = null; else first.next.prev = null; first = first.next; return first; } //删除表尾元素 public DuoLink deleteLast() throws Exception { if(isEmpty()) throw new Exception("空链表"); if(last.prev == null) first = null; else last.prev.next = null; last = last.prev; return last; } //删除元素 public DuoLink delete(int key) throws Exception { DuoLink find = find(key); if(find == null) throw new Exception("没有找到!"); else if(find == first) deleteFirst(); else if(find == last) deleteLast(); else { find.prev.next = find.next; find.next.prev = find.prev; find.next = null; find.prev = null; } return find; } //从头到尾显示 public void displayFromFirst() { DuoLink cr = first; StringBuffer sb = new StringBuffer(""); while(cr != null) { sb.append(cr.displayLink()+"\n"); cr = cr.next; } System.out.println(sb.toString()); } //从尾到头显示 public void displayFromLast() { DuoLink cr = last; StringBuffer sb = new StringBuffer(""); while(cr != null) { sb.append(cr.displayLink()+"\n"); cr = cr.prev; } System.out.println(sb.toString()); } //测试 public static void main(String[] args) throws Exception { DuoLinkedList dll = new DuoLinkedList(); dll.insertFirst(9); dll.insertFirst(4); dll.insertFirst(6); dll.insertFirst(3); dll.delete(4); dll.displayFromFirst(); } }
我们来测试一下:
<Key:3,Next:6,Prev:null> <Key:6,Next:9,Prev:3> <Key:9,Next:null,Prev:6>
相关文章推荐
- java实现双向循环链表和单链表
- Java 单链表的反转 以及 双向链表的实现
- Java单链表反转 Java实现单链表翻转
- 双向循环链表的Java版本实现
- JAVA实现双向链表的增删功能
- 数组、单链表和双链表介绍 以及 双向链表的C/C++/Java实现
- java实现双向链表
- 数据结构与算法分析笔记与总结(java实现)--二叉树22:二叉搜索树与双向链表
- 用java实现双向循环链表的增删改查
- 把二元查找树转变成排序的双向链表——Java实现
- Java实现双向链表
- java实现双向链表
- java实现双向循环链表
- java 实现双向链表(数据结构)
- 双向链表的Java实现
- JAVA单向/双向链表的实现
- java中双向链表的实现
- Java实现链表(单向和双向)
- java与数据结构(4)---java实现双向循环链表
- Java模拟单向链表和双向链表的实现