zoukankan      html  css  js  c++  java
  • 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");
        }
    
    
    }
    
    
  • 相关阅读:
    [WP8] ListBox的Item宽度自动填满
    [WP8] Binding时,依照DataType选择DataTemplate
    [CLK Framework] CLK.Threading.PortableTimer
    Sql Server 中 根据列名查询表名
    hMailServer SSL 配置
    SmtpClient SSL 发送邮件异常排查
    hMailServer 配置
    ADO.NET 连接池 Session 状态分析
    SqlBulkCopy 参数配置示例
    arrow css
  • 原文地址:https://www.cnblogs.com/hujesse4/p/15257138.html
Copyright © 2011-2022 走看看