Muốn được chỉ lỗi sai code về danh sách liên kết đơn trong Java

E đang học cách xây dựng danh sách liên kết đơn, e cài đặt nó theo gợi ý trong sách như thế này thì sai sót chỗ nào mong mọi người chỉ giúp e với ạ, e cảm ơn :sweat_smile: :sweat_smile: :sweat_smile: :sweat_smile:

package ctdl.gt;


public class dslk {
    Node head;
    public static void main(String[] args) {
        Node n1 = new Node();
        Node n2 = new Node();
        Node n3 = new Node();
        Node n4 = new Node();
        n1 = insertHead(head, 2);
        n2 = insertHead(head, 5);
        n3 = insertHead(head, 6);
        n4 = insertPrev(n2, 7);
        
    }
    
    //Node tail;
    public Node insertHead(Node head, int data){
       Node temp = new Node();
       temp.data = data;
       temp.next = head;
       head = temp;
       return temp;
    }
    public Node insertTail(Node head, int data){
        Node temp = new Node();
        Node newNode = new Node();
        newNode.data = data;
        temp.next = head.next;
        while(temp.next != null){
            temp = temp.next;
        }
        temp.next = newNode;
        return head;
    }
    public Node insertPrev(Node prev, int data){
        Node temp = new Node();
        temp.data = data;
        temp.next = prev.next;
        prev.next = temp;
        return temp;
    }
    
    //delete
    
    public Node deleteHead(Node head){
        Node temp = new Node();
        temp = head.next;
        head = temp;
        return head;
    }
    public Node deleteTail(Node head){
        Node temp1 = new Node();
        Node temp2 = new Node();
        temp1 = head;
        while(temp1.next != null){
            temp2 = temp1;
            temp1 = temp1.next;
        }
        temp2.next = null;
        return head;
    }
    public int deletePrev(Node prev){
        Node temp = new Node();
        temp = prev.next;
        prev.next = prev.next.next;
        int d = temp.data;
        return d;
    }
    
    // find
    
    
    //print
    public void display(Node head){
        Node temp = new Node();
        int count = 0;
        temp = head;
        while(temp !=null){
            System.out.println(temp.data);
            count++;
            temp =temp.next;
        }
        System.out.println("So phan tu cua dslk: " + count);
    }
}
class Node{
    int data;
    Node next;
}

Lỗi nulpointerexception đúng không, ngay ở dòng này, head là gì, đã gán giá trị đâu.

Hơn nữa cách cài đặt dslk của bạn tồn tại 1 lỗ hổng nghiêm trọng, hiện tại với test case bình thường thì có thể không nhận ra, nhưng rất nguy hiểm. Bạn không nên để biến next của node chơi vơi cho tất cả class có thể thay đổi giá trị như thế, hãy để việc này cho dslk và chỉ dslk implement thực hiện. Add các node đặc biệt thì phải có phương án check dữ liệu và đưa về các trạng thái hợp lệ trước khi thực hiện logic thật sự.

Hơn nữa cách cài đặt dslk của bạn chưa sử dụng được tính đóng gói của OOP

Đáng lẽ với mỗi phương thức, bạn nên tính trường hơp: danh sách chưa có phần tử hoặc danh sách có 1 phần tử

vậy là trong mỗi phương thức phải có 2 TH head.next == null và != null ạ

vâng, tại cũng nhiều chỗ e chưa hiểu
vậy ngay khi gọi phải gán head.next == null à anh hay viết thành 1 hàm dựng hay 1 cách nào khác

nope, null ở ngay chính cái head luôn, phải check head có null không đã

có phải là dùng hàm isEmpty k a?

A cho e xin fb a, e có nhiều điều muốn hỏi

có gì thì cứ hỏi trên này, còn nhiều người giúp nữa chứ k phải riêng mình mình. Hơn nữa cách bạn cài đặt dslk rất có vấn đề, trước tiên, hãy loại bỏ Node head ra tất cả các method, k nên bắt dependency quan tâm tới việc truyền head vào dslk, đấy là việc của chính dslk, hãy đảm bảo class ngoài k cần quan tâm dslk thực sự làm gì, các method nên simple nhất có thể, tránh để class bên ngoài đụng đến logic bên trong class dslk

A cho e ví dụ được k?

e biết code của e có vấn đề rồi, vậy có thể sửa cho nó hoàn chỉnh được không hay phải làm mới v a?

public class LinkedList {

    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
        linkedList.addHead(10);
        linkedList.addHead(15);

        int item = linkedList.getItem(0);
    }

    private Node head = null;
    private int mSize = 0;

    public void addHead(int value) {
        Node newHeadNode = new Node(value);
        if (head == null) { // no value yet
            head = newHeadNode;
        } else {
            newHeadNode.next = head;
            head = newHeadNode;
        }
        mSize++;
    }

    public void addTail(int value) {
        Node newTailNode = new Node(value);
        if (head == null) {
            head = newTailNode;
        } else {
            Node tailListNode = head;
            while (tailListNode.next != null) {
                tailListNode = tailListNode.next;
            }
            tailListNode.next = newTailNode;
        }
        mSize++;
    }

    public int getItem(int position) {
        if (position < 0 || position >= size()) {
            throw new IndexOutOfBoundsException("required index " + position + " but actually has " + (size() - 1));
        }
        Node valueNode = head;
        int currentPos = 0;
        while (currentPos < position) {
            valueNode = valueNode.next;
            currentPos++;
        }
        return valueNode.getValue();
    }

    public int size() {
        return mSize;
    }

    private static class Node {

        private int value;

        private Node next;

        public Node(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }

        public void setValue(int value){
            this.value = value;
        }
    }
}

đây là quick implement mình làm, bạn tham khảo, k hiểu đoạn nào thì hỏi mình. Như bạn thấy đấy, hàm main có sử dụng LinkedList do mình tạo ra, nó chỉ quan tâm đến việc add thêm đối tượng vào mà không cần quan tâm implement cụ thể, đối tượng làm việc chính chỉ là dữ liệu mà nó cần phải add thêm vào hoặc lấy ra chứ k cần quan tâm đến head/node của LinkedList cũng như tạo Node mới như thế nào, class Node chỉ được sinh ra bởi LinkedList và next node của 1 Node chỉ do LinkedList quản lí, bạn cũng nên biến các class thành các blackbox như thế, đây chính là tính đóng gói ứng dụng của OOP

Mình học UET đây là web môn học của bọn mình trong đó có bài giảng và code mẫu, mình thấy code mẫu rất đầy đủ và ngắn gọn, bạn có thể tham khảo :slight_smile:
https://sites.google.com/site/int22031/

thanks a, e đã hiểu ra vấn đề và cái sai trong cách e viết code rồi. e sẽ học thêm nhiều về OOP

Cảm ơn bạn nhiều lắm lắm :joy: :joy: , mình có thể làm quen được không, mình muốn có người trao đổi vì thật sự mình yếu môn này lắm

Cho mình xin cái đúng nào?

3 Likes

Để đến đích có thể đi nhiều con đường. Rất vui lòng được bạn chỉ ra chỗ sai (nếu có)

5 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?