一、鏈錶帶有前端節點和當前節點兩個成員變數,在進行操作的時候可以更加方便。而且都是帶有空頭結點的單向鏈表
package struct;import java.util.Scanner;/* * 註:此處的兩個成員變數許可權不能為private, * 因為private的許可權公對本類訪問*/class Node{int data;//資料域Node next;//指標域public Node(int data){this.data = data;}public Node(){}}public class Link {private Node head;//頭結點private Node current;//當前結點/* * 構造方法 */public Link(){head = null;current = head;}/* * 方法:向鏈表中添加結點 * 如果頭結點為空白,則說明鏈表還沒有建立,那就把新的結點賦給頭結點,將當前結點指向頭結點; * 如果頭結點不為空白,則建立新結點,放在當前結點的後端,並將鏈表的當前索引向後移動一位。 */public void add(int data){if(head == null){head = new Node(data);current = head;}else{current.next = new Node(data);current = current.next;}}/* * 方法:遍曆鏈表,即列印輸入鏈表 * 如果頭結點為空白,則列印NULL; * 如果頭結點不為空白,則讓鏈表當前索引移動到頭結點位置,從頭結點開始進行遍曆 */public void print(){if (head == null) {System.out.println("NULL");return;}else{current = head;while (current != null) {System.out.println(current.data);current = current.next;}}}/* * 方法:擷取鏈表的長度 * 如果頭結點為空白,要返回0; * 如果頭結點不為空白,則將當前索引移到頭結點位置,從頭結點開始遍曆統計長度 */public int length(){int length = 0;current = head;while (current != null) {length++;current = current.next;}return length;}/* * 方法:判斷鏈表是否為空白 * 如果頭結點為空白,返回true;否則返回false。 */public boolean isEmpty(){if (head == null) {return true;}return false;}/* * 方法:合并兩個有序(從小到大)鏈表,合并後有重複並且依然有序,並且返回合并後的鏈表 * 從兩個鏈表的頭結點開始比較,新鏈表就指向其中小的結點 */public Link merge(Link l1,Link l2){Link l = new Link();Node n1 = l1.head;Node n2 = l2.head;if(l1.isEmpty()){return l2;//如果l1為空白,則返回l2}else if(l2.isEmpty()){return l1;//如果l2為空白,則返回l1}//l1當前索引值比l2的小,則將新鏈表頭結點指向l1當前索引if(n1.data < n2.data){l.head =l.current = n1;n1 = n1.next;}else{//l2當前索引值小於等於l1的,則將新鏈表頭結點指向l2當前索引l.head = l.current = n2;n2 = n2.next;}while(n1!=null && n2!=null){//l1當前索引值比l2的小,則將新鏈表當前索引指向l1當前索引if(n1.data < n2.data){l.current.next = n1;l.current = l.current.next;n1 = n1.next;}else{//l2當前索引值小於等於l1的,則將新鏈表當前索引指向l2當前索引l.current.next = n2;l.current = l.current.next;n2 = n2.next;}}//此時l2中的元素已經合并完了,繼續合并l1中的元素while(n1 != null){l.current.next = n1;l.current = l.current.next;n1 = n1.next;}//此時l1中的元素已經合并完了,繼續合并l2中的元素while(n2 != null){l.current.next = n2;l.current = l.current.next;n2 = n2.next;}return l;}/* * 方法:返回帶前端節點的逆轉鏈表 * */public Link reverse(){Link link = new Link();link.head = new Node();Node old_head,new_head,tmp;new_head = null;old_head = head.next;while(old_head!=null){tmp = old_head.next;old_head.next = new_head;//將鏈表方向逆轉new_head = old_head;old_head = tmp;}link.head.next = new_head;//將要返回鏈表的頭結點指向新鏈表結點return link;}public static void main(String[] args) {Link link = new Link();//向鏈表中添加資料Scanner scan = new Scanner(System.in);System.out.println("請輸入資料……");for (int i = 0; i < 6; i++) {link.add(scan.nextInt());}Link l2 = new Link();System.out.println("鏈表的長度為:"+link.length());System.out.println("有一個空鏈表合并:");Link lin = link.merge(link, l2);lin.print();Link l1 = new Link();l1.add(3);l1.add(5);l1.add(6);l1.add(8);System.out.println("兩個非空有序鏈表合并:");lin = link.merge(link,l1);lin.print();Link ll = lin.reverse();ll.print();}}
輸出的結果為:
請輸入資料……1 2 3 4 5 6鏈表的長度為:6有一個空鏈表合并:1 2 3 4 5 6 兩個非空有序鏈表合并:1 2 3 3 4 5 5 6 6 8 鏈表逆轉後:8 6 6 5 5 4 3 3 2 1
二、只有頭結點的單向鏈表,為了方便操作,每次都要建立一個節點,代替鏈表的前端節點。這裡是不帶空前端節點的鏈表
package struct;<pre name="code" class="java">class Node{int data;//資料域Node next;//指標域public Node(int data){this.data = data;}public Node(){}}
/* * 不帶頭結點的鏈表 */public class LinkList {private Node head;// 建構函式public LinkList() {head = null;}// 向鏈表頭部插入一個元素public void insertFirst(int val) {Node newlink = new Node();newlink.data = val;newlink.next = head;head = newlink;}// 向鏈表尾部部插入一個元素public void insertLast(int val) {Node newlink = new Node();newlink.data = val;if(isEmpty()){head = newlink;return;}Node current = getCurrent();current.next = newlink;}// 從鏈表的頭結點處刪除一個元素public void deleteFirst() {Node temp = head.next;head = temp;}// 判斷鏈表是否為空白public boolean isEmpty() {return (head == null);}// 列印鏈表(從前端節點的元素開始列印)public void display() {Node current = head;if (isEmpty()) {System.out.println("NULL");return;}while (current != null) {System.out.print(current.data + " ");current = current.next;}System.out.println();}// 返回鏈表的當前節點public Node getCurrent() {Node current = new Node();current = head;while (current.next != null) {current = current.next;}return current;}/* * 鏈表的逆轉 * 1、將原前端節點的下一個節點暫存在temp中; * 2、將原前端節點指向新前端節點; * 3、新前端節點跳轉到原前端節點; * 4、原前端節點跳轉到temp; * 5、最後把新鏈表的前端節點跳轉到新前端節點。 */public LinkList reverse(){LinkList list = new LinkList();Node temp,old_head,new_head;old_head = head;new_head = null;while(old_head != null){temp = old_head.next;old_head.next = new_head;new_head = old_head;old_head = temp;}list.head = new_head;return list;}//判斷元素是否存在於鏈表中public boolean isExist(int val){Node current = head;while(current != null){if(current.data == val){return true;}current = current.next;}return false;}public static void main(String[] args) {LinkList l1 = new LinkList();l1.insertLast(1);l1.insertLast(2);l1.insertLast(3);l1.insertLast(4);l1.insertLast(5);System.out.println("鏈表1:");l1.display();LinkList l2 = new LinkList();l2.insertLast(3);l2.insertLast(5);l2.insertLast(7);System.out.println("鏈表2:");l2.display();LinkList l = merge(l1,l2);System.out.println("兩鏈表合并後:");l.display();l = l.reverse();System.out.println("鏈表逆轉後:");l.display();}//合并兩個有序單身鏈表public static LinkList merge(LinkList l1,LinkList l2){LinkList link = new LinkList();if(l1.isEmpty()){//如果l1為空白,則返回l2return l2;}if(l2.isEmpty()){//如果l2為空白,則返回l1return l1;}Node link1 = l1.head;Node link2 = l2.head;Node linkHead = new Node();link.head = linkHead;while (link1!=null && link2!=null){if(link1.data < link2.data){linkHead.next = link1;link1 = link1.next;linkHead = linkHead.next;}else{linkHead.next = link2;linkHead = linkHead.next;link2 = link2.next;}}while (link1 != null) {linkHead.next = link1;linkHead = linkHead.next;link1 = link1.next;}while (link2 != null) {linkHead.next = link2;linkHead = linkHead.next;link2 = link2.next;}link.head = link.head.next;//把頭結點去掉return link;}}
輸出的結果為:
鏈表1:1 2 3 4 5 鏈表2:3 5 7 兩鏈表合并後:1 2 3 3 4 5 5 7 鏈表逆轉後:7 5 5 4 3 3 2 1