2021/9/11数据结构(一)单链表

9.11 begin 数结(单向链表最佳实现)

常见面试题:

  1. 字符串模式匹配(KMP)
  2. 汉诺塔(分治)
  3. 八皇后(回溯)
  4. 马踏棋盘(图的深度优先+贪心算法)

课程目标:掌握本质,能达到在工作中灵活运用解决实际问题和优化程序。

程序 = 数据结构 + 算法

数据结构分类:

  • 线性结构
  • 非线性结构

Today 的第一个code为 Java单链表

在写链表之前,我们来讨论一下什么是引用,因为这挺重要的。

​ 是指创建一个对象并把这个对象赋给一个引用变量。

在内存上申请一块内存,一个变量object引用它。

Object object = new Object();

·如果没有实现构造函数,系统会默认加上一个无参数的构造函数。·

package LinkedList;

/**
 * 我定义的单向链表,其中第一个元素index为1
 *
 * @param <T>
 */
public class MyLinkedList<T> {
    private Node<T> head;
    private Node<T> tail;
    private int size; //仅仅记录链表长度,不做规定
    private class Node<T>{
        private T data;
        private Node<T> next;
        public Node() {
            data = null;
            next = null;
        }
        public Node(T data) {
            this.data = data;
            next = null;
        }
        @Override
        public String toString() {
            return "Node{" +
                    "data=" + data +
                    ", next=" + next +
                    '}';
        }
    }
    public int getSize(){
        return this.size;
    }
    //构造函数
    public MyLinkedList(){
        this.head = null;
        this.tail = null;
        this.size = 0;
    }
    public T getFirst() throws Exception{
        rangeCheck();
        return this.head.data;
    }
    private void rangeCheck() throws Exception {
        if (isEmpty()) {
            throw new Exception("List is empty");
        }
    }
    private void indexCheck(int index) throws Exception{
        if (index>this.size || index<=0){
            throw new IllegalArgumentException("Illegal Index");
        }
    }
    public T getLast() throws Exception{
        rangeCheck();
        return this.tail.data;
    }
    public Boolean isEmpty(){
        return this.size == 0;
    }
    public Boolean isNotEmpty(){
        return !isEmpty();
    }
    /**
     我定义第一个节点就为头节点,最后一个节点为size大小,index 从一开始
     */
    public T getAt(int index) throws Exception{
        return (T) getNodeAt(index).data;
    }
    /**
     * 根据Node中的data查找在表中的位序
     * @param data
     */
    public int getIndexAt(T data) throws Exception{
        int index = 1;
        rangeCheck();
        Node<T> tmp = this.head;
        while(tmp!=null && tmp.data!=data){
            tmp = tmp.next;
            index++;
        }
        if (tmp==null) return -1;
        else return index;
    }
    public Node getNodeAt(int index) throws Exception{
        rangeCheck();
        indexCheck(index);
        Node<T> temp = this.head;
        for (int i = 1; i <=index-1 ; i++) {
            temp = temp.next; // 这段代码多多理解。temp = 一个内存地址
        }
        return temp;
    }
    /**
     * 尾插法
     * @param data
     */
    public void addLast(T data){
        // create
        Node<T> node = new Node();
        node.data = data;
        // attach
        if (isNotEmpty()) {
            this.tail.next = node;
        }
        if (isEmpty()){
            this.head = node;
        }
        this.tail = node;
        this.size +=1;
    }
    /**
     * 头插法
     * @param data
     */
    public void addFirst(T data){
        Node<T> node = new Node();
        node.data = data;
        if (isNotEmpty()){
            node.next = head;
        }
        if (isEmpty()){
            this.tail = node;
        }
        this.head = node;
        this.size +=1;
    }
    /**
     * 假如idx=1,那么头插,如果idx>siz,尾插
     * @param data
     * @param idx
     */
    public void addAt(T data,int idx) throws Exception{
        if (idx<=0){
            throw new IllegalArgumentException("Illegal Index");
        }
        if (idx == 1){
            addFirst(data);
        }else if(idx>size){
            addLast(data);
        }
        Node<T> node = new Node();
        node.data = data;
        Node preNode = getNodeAt(idx-1);
        node.next = preNode.next;
        preNode.next = node;
    }
    public T removeFirst() throws Exception{
        rangeCheck();
        Node<T> tmp = this.head;
        if (this.size ==1 ){
            this.head = null;
            this.tail = null;
            this.size =0;
        }else {
            head = head.next;
            this.size--;
        }
        return tmp.data;
    }
    public T removeLast() throws Exception{
        rangeCheck();
        if (this.size ==1 ){
            this.head = null;
            this.tail = null;
            this.size =0;
        }
        Node<T> tmp = this.tail;
       Node preNode =  getNodeAt(this.size-1);
        preNode.next = null;
       this.tail = preNode;
       this.size--;
       return tmp.data;
    }
    public T removeAt(int idx) throws Exception{
        rangeCheck();
        indexCheck(idx);
        if (idx == 1){
            removeFirst();
        }else if(idx ==this.size){
            removeLast();
        }
        Node<T> prefix = getNodeAt(idx - 1);
        Node<T> removeNode = prefix.next;
        prefix.next = removeNode.next;
        this.size --;
        return removeNode.data;
    }
    public void removeAll() throws Exception {
        while (this.size>0){
            removeFirst();
        }
    }
    public void display(){
        System.out.println("========================");
        Node temp = this.head;
        while(temp!=null){
            System.out.println(temp.data);
            temp = temp.next;
        }
        System.out.println("Over");
    }


}

posted @ 2021-09-11 23:40  能借我十块钱吗  阅读(34)  评论(1编辑  收藏  举报