面试---数据结构(3)(链表)

1**除了用数组描述线性表还可以用链表描述线性表**
2在链式描述中,线性表的元素在内存中的存储位置是随机的。每个元素都有一个明确的指针或链指向线性表的下一个元素的位置(即地址)
*数组和链表的区别:
在数组中,元素的地址是由数学公式决定的,而在链式描述中,元素的地址是随机分布的
顺序表是顺序存储,非顺序存取,链表是非顺序存储。顺序存取
因此链式表便于插入,删除操作,不便于查询

3链表分为单向链表,双向链表和循环链表
首先用图片来说一下单向链表:
这里写图片描述

代码实现增删改查:

package com.tyxh.link;
//节点类
public class Node {
     protected Node next; //指针域
     protected int data;//数据域

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

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

package com.tyxh.link;
//单链表
public class LinkList {
     public Node first; // 定义一个头结点
     private int pos = 0;// 节点的位置

     public LinkList() {
           this. first = null;
     }

     // 插入一个头节点
     public void addFirstNode( int data) {
          Node node = new Node(data);
          node. next = first;
           first = node;
     }

     // 删除一个头结点,并返回头结点
     public Node deleteFirstNode() {
          Node tempNode = first;
           first = tempNode. next;
           return tempNode;
     }

     // 在任意位置插入节点 在index的后面插入
     public void add(int index, int data) {
          Node node = new Node(data);
          Node current = first;
          Node previous = first;
           while ( pos != index) {
              previous = current;
              current = current. next;
               pos++;
          }
          node. next = current;
          previous. next = node;
           pos = 0;
     }

     // 删除任意位置的节点
     public Node deleteByPos( int index) {
          Node current = first;
          Node previous = first;
           while ( pos != index) {
               pos++;
              previous = current;
              current = current. next;
          }
           if(current == first) {
               first = first. next;
          } else {
               pos = 0;
              previous. next = current. next;
          }
           return current;
     }

     // 根据节点的data删除节点(仅仅删除第一个)
     public Node deleteByData( int data) {
          Node current = first;
          Node previous = first; //记住上一个节点
           while (current. data != data) {
               if (current. next == null) {
                    return null;
              }
              previous = current;
              current = current. next;
          }
           if(current == first) {
               first = first. next;
          } else {
              previous. next = current. next;
          }
           return current;
     }

     // 显示出所有的节点信息
     public void displayAllNodes() {
          Node current = first;
           while (current != null) {
              current.display();
              current = current. next;
          }
          System. out.println();
     }

     // 根据位置查找节点信息
     public Node findByPos( int index) {
          Node current = first;
           if ( pos != index) {
              current = current. next;
               pos++;
          }
           return current;
     }

     // 根据数据查找节点信息
     public Node findByData( int data) {
          Node current = first;
           while (current. data != data) {
               if (current. next == null)
                    return null;
              current = current. next;
          }
           return current;
     }
}

package com.tyxh.link;
//测试类
public class TestLinkList {
     public static void main(String[] args) {
          LinkList linkList = new LinkList();
          linkList.addFirstNode(20);
          linkList.addFirstNode(21);
          linkList.addFirstNode(19);
           //19,21,20
          linkList.add(1, 22); //19,22,21,20
          linkList.add(2, 23); //19,22,23,21,20
          linkList.add(3, 99); //19,22,23,99,21,20
          linkList.displayAllNodes();
//        Node node = linkList.deleteFirstNode();
//        System.out.println("node : " + node.data);
//        linkList.displayAllNodes();
//        node = linkList.deleteByPos(2);
//        System.out.println("node : " + node.data);
//        linkList.displayAllNodes();
//        linkList.deleteFirstNode();
          Node node = linkList.deleteByData(19);
//        Node node = linkList.deleteByPos(0);
          System. out.println( "node : " + node. data);
          linkList.displayAllNodes();
          Node node1 = linkList.findByPos(0);
          System. out.println( "node1: " + node1. data);
          Node node2 = linkList.findByData(22);
          System. out.println( "node2: " + node2. data);
     }
}

再就是双向链表:
这里写图片描述

public class DoubleLinkedList  
{  
  // 节点类Node  

  private static class Node  
  {  
    Object value;  
    Node prev = this;  
    Node next = this;  

    Node(Object v)  
    {  
      value = v;  
    }  

    public String toString()  
    {  
      return value.toString();  
    }  
  }  
  private Node head = new Node(null); // 头节点  
  private int size; // 链表大小  
  // 以下是接口方法  

  //添加到链表表头
  public boolean addFirst(Object o)  
  {  
    addAfter(new Node(o), head);  
    return true;  
  }  
  //将元素添加到链表表尾
  public boolean addLast(Object o)  
  {  
    addBefore(new Node(o), head);  
    return true;  
  }  

  public boolean add(Object o)  
  {  
    return addLast(o);  
  }  
  //将元素添加到指定位置
  public boolean add(int index, Object o)  
  {  
    addBefore(new Node(o), getNode(index));  
    return true;  
  }  
  //移除指定位置
  public boolean remove(int index)  
  {  
    removeNode(getNode(index));  
    return true;  
  }  
  //移除链表表头元素
  public boolean removeFirst()  
  {  
    removeNode(head.next);  
    return true;  
  }  
  //移除链表表尾元素
  public boolean removeLast()  
  {  
    removeNode(head.prev);  
    return true;  
  }  
  //取到指定位置的元素值
  public Object get(int index)  
  {  
    return getNode(index).value;  
  }  
  //返回链表的大小
  public int size()  
  {  
    return size;  
  }  

  public String toString()  
  {  
    StringBuffer s = new StringBuffer("[");  
    Node node = head;  
    for (int i = 0; i < size; i++)  
    {  
      node = node.next;  
      if (i > 0)  
        s.append(", ");  
      s.append(node.value);  
    }  
    s.append("]");  
    return s.toString();  
  }  
  //以下是实现方法  

  //查找链表元素
  private Node getNode(int index)  
  {  
      if (index < 0 || index >= size)  
          throw new IndexOutOfBoundsException();  
        Node node = head.next;  
        for (int i = 0; i < index; i++)  
          node = node.next;  
        return node; 
  }  
  //在某元素之前添加元素
  private void addBefore(Node newNode, Node node)  
  {  
    newNode.prev = node.prev;
    newNode.next = node;
    newNode.next.prev = newNode;
    newNode.prev.next = newNode;
    size++;
  }  
  //在某元素之后添加元素
  private void addAfter(Node newNode, Node node)  
  {  
      newNode.prev = node;
      newNode.next = node.next;
      newNode.next.prev = newNode;
      newNode.prev.next = newNode;
      size++;
  }  
  //移除特定元素
  private void removeNode(Node node)  
  {  
    node.next.prev = node.prev;
    node.prev.next = node.next;
    node.prev = null;
    node.next = null;
    size--;
  }  
}  
//有些地方还可以优化,比如查找时可以判断索引是否大于size的一半,如果是的话,就从另一头开始迭代。  

测试类
public class Test  
{  
public static void main(String[] args)  
{  
  DoubleLinkedList dll = new DoubleLinkedList();  
  //添加  
  dll.add("A");  
  dll.add("B");  
  dll.add("C");  
  System.out.println(dll);  

  //添加到最前  
  dll.addFirst("D");  
  System.out.println(dll);  

  //添加到最后 
  dll.addLast("E");  
  System.out.println(dll);

  //添加到指定位置  
  dll.add(4, "F");  
  System.out.println(dll);  

  //移除最前的  
  dll.removeFirst();  
  System.out.println(dll);  

  //移除最后的  
  dll.removeLast();  
  System.out.println(dll);  

  //移除指定位置上的  
  dll.remove(2);  
  System.out.println(dll);  

  //返回指定位置上的元素  
  System.out.println(dll.get(1));  

}  
}  
1

循环链表:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值