單鏈表

//無論單鏈表還是雙鏈表,節點插入都遵循先立後破的原則,即新節點指針先指向原有節點,然後再將原有節點指針指向新節點
//操作時,需要注意鏈表的頭尾節點
import java.util.*;
import java.io.*;
//頭結點,鏈表是否爲空,當前節點,鏈表長度,添加節點,
public class linklist{
	public int len=1;//可以沒有
	public Node head;//必須有頭結點屬性,有了頭結點啥都好辦
	
	/*插入一個節點,位置爲鏈表頭節點之後,*/
	void add(Node e){
		if (this.head==null) {//檢查是否爲空,若爲空添加節點爲頭節點
		 	this.head=e;
		}
		else if (this.head.next==null) {//檢查節點數是否大於2,若否,添加節點爲第二個節點
		 	head.next=e;
		 	this.len++;
		}
		else {//添加節點到頭結點之後
		 	e.next=this.head.next;
		 	this.head.next=e;
		 	this.len++;
		}
	}
	/*獲取鏈表的長度, 假設鏈表沒有len屬性*/
	int GetLen( ){//或int GetLen(linklist list)
			int length=1;
		if (this.head==null) {
		 	length=0;
		}
	
		Node current=this.head;
		while (current.next!=null) {
			length++;
			current=current.next;
		}
		return length;
	}
/*查找鏈表倒數第k個節點,若要求不能求鏈表長度,則需要兩個指針,兩者偏移K(詳見參考博客)*/
	Node FindNode(int k){
		int len = this.GetLen();//鏈表長度
		Node current =this.head;
		for (int i=0; i<len-k; i++) {
		 	current=current.next;
		}
		return current;	
	}
	
/*合併兩個有序的單鏈表,合併之後的鏈表依然有序【出現頻率高】(劍指offer,題17)*/
	public  Node MergeNode(Node e1,Node e2){//返回鏈表頭結點
	
		

		Node current1=e1;		
		Node current2=e2;

		Node head=current1.data<current2.data? current1:current2;//先把頭結點放入新鏈表
		current1=current1.next;
		current2=current2.next;
		Node current=head;
		while (current1.next!=null && current2.next!=null) {//若兩個鏈表都不爲空,比較兩個鏈表的元素,把小的放入新鏈表
			if (current1.data<current2.data) {//if..else即可,無需while
				current.next=current1;//這裏注意理解
				current1=current1.next;
				current=current.next;
			}
			else  {
				current.next=current2;
				current2=current1.next;
				current=current.next;
			}
		}

		if (current1.next!=null ) {
				current.next=current1;

		}
		if (current2.next!=null ) {
				current.next=current2;

		}
		
		return head;
	}
	/*打印單鏈表*/
	
	public void Print(){
		Node current=this.head;
		for (int i=0; i<this.GetLen(); i++) {
			System.out.println(current.data);
			current=current.next;	
		}
	}
/*單鏈表反轉*/
	public Node  Inverse(){
		
			Node e1=this.head;//Node e1=new Node();//這樣不對,因爲你的Node類中構造方法必須傳參數
			Node current=this.head;
			current=current.next;

			while(current!=null){
				Node e=current;//新建一個節點,臨時節點
			 	e.next=e1;//新建節點的next指向l新鏈表當前頭結點e1
			 	e1=e;//調整鏈表的頭結點			 
			 	current=current.next;	
/*			  next = current.next; //暫時保存住當前結點的下一個結點,因爲下一次要用    
			  current.next = e1; //將current的下一個結點指向新鏈表的頭結點  
			  e1 = current;    
			  current = next; // 操作結束後,current節點後移 	*/
			}
			return e1;//返回頭結點
	}
	
/*測試*/
	public static void  main(String[] args){//測試,初始化一個鏈表
		linklist list1=new linklist();//創建鏈表對象
		linklist list2=new linklist();
		linklist  list12= new linklist();
		for (int i=8; i<15; i++) {
		 	list1.add(new Node(i));
		}
		
		for (int i=3; i<8; i++) {
		 	list2.add(new Node(i));
		}
		//Node e1 =list1.head;
		//Node e2=list2.head;
	//	Node e=list12.MergeNode(e1,e2);
	//	list12.head=e;

		list1.Inverse();
		list1.Print();
		//list12.Print();
		//System.out.println("鏈表長度:"+list12.GetLen());//獲取鏈表長度
		//System.out.println(list1.GetLen());//查找倒數第3個節點,並輸出節點元素list1.GetLen()+
		//System.out.println("合併的鏈表頭結點:"+e.data);//獲取鏈表長度

	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章