单链表与双向链表的Java实现

来源:互联网 发布:励志的网络流行语 编辑:程序博客网 时间:2024/05/21 17:15

链表是一种物理存储单元上非连续、非顺序的存储结构。链表的机制灵活,它可以替代数组成为栈、队列的基础存储结构。链表比数组来说,没有大小限制,插入删除不基本需要移动元素。

链表的概念,就像有一群人,其中一个人举起一面旗子。而其他的人必须抓住另一个的后背,而且只能抓住一个。这样,所有的人就形成了一条人链,这个结构就是链表,而人就是链节点。

首先,我们先将链节点的代码写上:

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("链表为空。");elsesb.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;elsecrtParent.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;elsecrtParent.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;elsefirst.next.prev = null;first = first.next;return first;}//删除表尾元素public DuoLink deleteLast() throws Exception{if(isEmpty())throw new Exception("空链表");if(last.prev == null)first = null;elselast.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>
原创粉丝点击