Java數據結構——不帶頭單向非循環鏈表

一、鏈表的概念

鏈表:採用鏈式存儲結構存儲的線性表,所謂的鏈式是指每個節點保存下一個節點的引用

鏈表的分類:

  • 單向、雙向
  • 帶頭節點、不帶頭節點
  • 循環、非循環

根據以上三種分類,即可組成八種不同類型的鏈表

鏈表的特點:

鏈表結構可以充分利用計算機內存空間,實現靈活的內存動態管理,但是鏈表失去了順序表可以隨機讀取的優點,同時,鏈表增加了節點的指針域,空間開銷比較大。

二、不帶頭單向非循環鏈表              

1.結構圖 

                 

2. 節點類組成

class Node {  //內部節點類
        private int data;  //節點數據
        private Node next;  //下一個節點引用
        public Node(int data) {  //帶參數的構造方法,用於實例化普通節點
            this.data = data;
            this.next = null;
        }
        //頭結點
        public Node() {  //不帶參數的構造方法,用於實例化頭節點
            this.data = -1;
            this.next = null;
        }
    }

3. 常用的鏈表操作

1)遍歷鏈表

2)頭插法

 

3)尾插法

 

4) 任意位置插入

5) 刪除第一次出現關鍵字爲key的節點

6)  刪除所有關鍵字爲key的節點

7)清空鏈表 

 

4. 接口

public interface ILinked {
    //頭插法
    void addFirst(int data);
    //尾插法
    void addLast(int data);
    //任意位置插入,第一個數據節點爲0號下標
    boolean addIndex(int index,int data);
    //查找是否包含關鍵字key是否在單鏈表當中
    boolean contains(int key);
    //刪除第一次出現關鍵字爲key的節點
    int remove(int key);
    //刪除所有值爲key的節點
    void removeAllKey(int key);
    //得到單鏈表的長度
    int getLength();
    void display();
    void clear();
}

5. 實現類

public class MySingleList implements ILinked{
    //內部節點類
    class Node {
        private int data;//存儲該節點中的元素
        public Node next;//引用下一個節點

        //節點類構造方法
        public Node(int data) {
            this.data = data;
            this.next = null;
        } 
    }

    private Node head;//頭節點

    //鏈表類構造方法
    public MySingleList() {
        this.head = null;
    }

    @Override
    //頭插法
    public void addFirst(int data) {
        Node node = new Node(data);//新建一個插入節點
        if(this.head == null) {//頭節點爲空,則插入節點爲頭節點
            this.head = node;
        }else {//頭節點不爲空
            node.next = this.head;
            this.head = node;
        }
    }

    @Override
    //尾插法
    public void addLast(int data) {
        Node node = new Node(data);
        Node cur = this.head;
        //如果是第一次插入
        if(cur == null) {
            this.head = node;
        }else {
            //1、找尾巴
            while(cur.next != null) {
                cur = cur.next;
            }
            //退出上面的循環,cur所指向的位置就是尾節點
            cur.next = node;
        }
    }

// 返回index位置的節點
    private Node searchIndex(int index){
        checkIndex(index);
        int count=0;
        Node cur=this.head;
        while(count<index-1){
            cur=cur.next;
            count++;
        }
        return cur;
    }
    //檢驗index位置合法性
    private void checkIndex(int index){
        if(index<0||index>getLength()){
            throw new UnsupportedOperationException("index位置不合法");
        }
    }

    @Override
    //任意位置插入
    public boolean addIndex(int index, int data) {
    if(index==0){
        addFirst(data);
        return true;
    }
    Node node =new Node(data);
    Node cur=searchIndex(index);
    node.next=cur.next;
    cur.next=node;
    return true;
    }

    @Override
    //查找是否包含關鍵字key是否在單鏈表當中
    public boolean contains(int key) {
        Node cur=this.head;
        while(cur!=null){
            if(cur.data==key){
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

    private Node searchPrev(int key){
        Node cur=this.head;
        while(cur.next!=null){
            if(cur.next.data==key){
                return cur;
            }
           cur=cur.next;
        }
        return null;
    }
    @Override
    //刪除第一次出現關鍵字爲key的節點
    public int remove(int key) {
        if(this.head == null) {
            throw new UnsupportedOperationException("單鏈表爲空");
        }
        int oldData = 0;
        //刪除的節點是頭結點
        if(this.head.data == key){
            oldData = this.head.data;
            this.head = this.head.next;
            return oldData;
        }
        Node prev = searchPrev(key);
        if(prev == null) {
            //return
            throw new UnsupportedOperationException("沒有前驅");
        }
        Node del = prev.next;
        oldData = del.data;
        prev.next = del.next;
        //del = null;
        return oldData;
    }

//刪除所有關鍵字爲key的節點
    public void removeAllKey(int key) {
        if(this.head == null) {
            return;
        }
        Node prev = this.head;
        Node cur = this.head.next;
        while (cur != null) {
            if(cur.data == key){
                prev.next = cur.next;
                cur = prev.next;
            }else {
                prev = cur;
                cur = cur.next;
            }
        }
        if(this.head.data == key){
            this.head = this.head.next;
        }
    }

    @Override
    public int getLength() {
        if(this.head == null) {
            return 0;
        }
        int count = 0;
        Node cur = this.head;
        while (cur != null){
            count++;
            cur = cur.next;
        }
        return count;
    }
    @Override
    public void display() {
        Node cur = this.head;
        while(cur != null) {
            System.out.print(cur.data+" ");
            cur = cur.next;
        }
        System.out.println();
    }

    @Override
    public void clear() {
        while (this.head.next != null) {
            Node del = this.head.next;
            this.head.next = del.next;
        }
        this.head = null;
    }

 

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