链表

链表(Linked list)是一种常见的线性数据结构。单向链表中每个结点都有一个next指针指向下一个结点,双向链表则多一个指向上一个结点的指针。搜索链表和查找第n个数据的时间复杂度都是O(n)。链表的优势在于在任意位置删除和插入数据时效率高(不用改变其他节点位置)

一. 单链表的定义以及一些基本操作实现(java)

/* 
 * 定义一个结点类
 */ 
public class Node {
    Node next;          //指向下一结点的指针
    int data;           //该节点存储数据

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

    //显示此结点
    public void show(){
        System.out.print(data + " ");
    }
}

/* 
 * 定义一个链表主类,并且定义各种对链表操作的方法 
 */ 
public class List {
    public Node head;              //定义一个头结点
    public Node tail;              //定义一个尾指针

    //定义一个空链表
    public List(){
        head = null;
        tail = head;
    }

    //插入结点(2种)
    public void addToList(int data){              //1.在尾部直接插入
        Node node = new Node(data);
        if(head == null){
            head = node;
        }else{
            tail.next = node;
        }
        tail = node;
    }

    public void addToList(int index, int data){  //2.在任意位置插入
        Node node = head;
        int i = 0;
        while(node!=null && i<index-2){
            node = node.next;
            i++;
        }
        Node insert = new Node(data);
        insert.next = node.next;
        node.next = insert;
    }

    //删除一个结点(2种)
    public void deleteByIndex(int index){          //1.根据位置删除
        Node node = head;
        int i = 0;
        while(node!=null && i<index-2){
            node = node.next;
            i++;
        }
        node.next = node.next.next;
    }

    public void deleteByData(int data){          //2.根据数据删除(只操作第一个)
        Node current = head;  
        Node previous = head; //记住上一个节点 
        int i = 0;
        while (current.data != data){
            if(current.next == null){
                i = 1;
                break;
            }
            previous = current;  
            current = current.next;  
        }
        if(i==0){
            if(current == head) {  
                head = head.next;  
            }else{  
                previous.next = current.next;  
            }
        }

    }

    //改变指定位置的结点数值
    public void change(int index, int data){
        Node node = head;
        int i = 0;
        while(node!=null && i<index-2){
            node = node.next;
            i++;
        }
        node.next.data = data;
    }

    //查找结点信息(3种)
    public void showAllNodes(){                   //1.显示所有结点信息
        Node node = head;                         //还可以用递归形式遍历
        while(node!=null){
            node.show();
            node = node.next;
        }
        System.out.println();
    }

    public Node findByIndex(int index){              //2.根据位置查找
        Node node = head;
        int i = 0;
        while(node!=null && i<index-1){
            node = node.next;
            i++;
        }
        return node;
    }

    public Node findByData(int data){            //3.根据数据查找(只操作第一个)
        Node current = head;
        while(current.data != data){
            if(current.next == null)
                return null;
            else
                current = current.next;
        }
        return current;
    }
}

二. 面试中经常出现的链表相关问题(用java实现)

(没有实现的,后续一一补充)

  • 1.求单链表中结点的个数
public int getLength(Node head){
        if(head == null){
            return 0;
        }                                //注意链表为空时的情况
        else{
            Node node = head;
            int length = 0;
            while(node != null){
                length++;
                node = node.next;
            }
            return length;
        }
}
  • 2.将单链表反转

  • 3.查找单链表中的倒数第K个结点(k > 0)

  • 4.查找单链表的中间结点

  • 5.从尾到头打印单链表

  • 6.已知两个单链表各自有序,把它们合并成一个链表依然有序

  • 7.判断一个单链表中是否有环

  • 8.判断两个单链表是否相交

  • 9.求两个单链表相交的第一个节点

  • 10.已知一个单链表中存在环,求进入环中的第一个节点

  • 11.给出一单链表头指针和一节点指针,O(1)时间复杂度删除该节点

posted @ 2017-07-10 22:19  xs_zhou  阅读(88)  评论(0编辑  收藏  举报