1. 程式人生 > >java與資料結構之---連結串列

java與資料結構之---連結串列

//利用JAVA實現資料結構,
//後再去理解Java中集合的概念
//以下為連結串列 這種資料結構


package myFirstJava;

import java.util.Scanner;

public class ListNode {
    
    ///設定head
    Node head = null;
	/////節點類
	class Node{
		int val = -1;
		Node next = null;
		Node(int val){
			this.val = val;
		}
	}
	
	////新增節點
	public void addNode(int v){
		Node node = new Node(v);
        if(head == null){
        	head = node;
        }
        else{
        Node point = head;
        while(point.next!=null){
        	point = point.next;
        }
        point.next = node;
        }
	}
	///刪除節點
	public void DeleteNode(int t){
		int i = 0;
		Node point = head;
		while(point.next!=null){
			i++;
			if(i == t-1){
				break;
			}
			point = point.next;
		}
		point.next = point.next.next;
	}
	///返回連結串列長度
	public int ListLength(){
		int length = 0;
		Node point = head;
	    while(point!=null){
	    	length++;
	    	point = point.next;
	    }
		return length;
	}
	
	
	///列印連結串列
	public void PrintList(){
		Node point = head;
		
		while(point!=null){
			if(point == head){
				System.out.print(point.val);
			}
			else
			System.out.print("->"+point.val);
		    point = point.next;
		}
		System.out.print('\n');
	}

	
	public static void main(String[] args){
	   Scanner sc = new Scanner(System.in);
	   ListNode ListNode = new ListNode();
	   for(int i = 0; i < 30; i++){
		   ListNode.addNode(i);
	   }
      
       while(sc.hasNext()){
    	   int choice = sc.nextInt();
    	   switch(choice%9){
    	   case 0://刪除
    		   ListNode.DeleteNode(3);
    		   break;
    	   case 1: //列印
    		   ListNode.PrintList();
    		   break;
    	   case 2://輸出長度
    		   System.out.println(ListNode.ListLength());
    		   break;
    	   case 3://增加
    		   ListNode.addNode(choice);
    		   break;
    	   case 4://去重
               ListNode.DeleteRepeat();
               break;
    	   case 5://倒序
               ListNode.printListReserve(ListNode.head);
               break;
    	   case 6://末尾查詢
    		   ListNode.reciprocalNode(3);
    	   case 7://中間節點查詢
               ListNode.searchMiddleNode();
    	   }   
       }
       sc.close();
	}
	
	
	/////////
	/////////  連結串列中的其他複雜操作
	/////////
	
	//1.刪除連結串列中的重複元素
	public int DeleteRepeat(){
		int num = 0;
		Node point1 = head;
		Node point2 = null;
		
		while(point1!=null){
			point2 = point1;
			while(point2.next!=null){
				if(point2.next.val == point1.val){
					point2.next = point2.next.next;
					num++;
					continue;
				}
				point2 = point2.next;
			}
		     	point1 = point1.next;
		}
		return num;
	}
	// **2.遞迴實現倒序輸出整個連結串列
	public void printListReserve(Node point){
		if(point==null){
			return;
		}
		printListReserve(point.next);
		System.out.print(point.val+"->");
		
	}
	
	// 3.查詢倒數第k個元素  
	 public void reciprocalNode(int k){
			Node p1 = head;
			while(k-->=0){ 
				p1 = p1.next;
			}
			Node p2 = head;
			while(p1.next!=null){
				p1 = p1.next;
				p2 = p2.next;
			}
			System.out.println(p2.val);
			return;
	  }
     // 4.查詢連結串列的中間節點
	 // 採用快慢指標的方法,定義2個指標,一個每次走1步,一個每次走2步,後者走到盡頭的時候,前者走到中點
	 public void searchMiddleNode(){
		    Node p1 = head;
		    Node p2 = head;
		    while(p2!=null&&p2.next!=null){
		    	p2 = p2.next.next;
		    	p1 = p1.next;
		    }
		    System.out.println(p1.val);
	 }
	 
}