常见数据结构之链表

一、链表基本定义及特点:

1、链表是通过指针零散的内存块串联起来组成的数据存储结构。

简单模型单链表结构   链表结构:head+next------data+next------data+next-------end+next(null)

  • head  :用来存储链表的基地址。
  • 其他数据节点:data+next -----data+next 其中next存储指向下一个节点的地址
  • 尾节点; end+next  尾节点的next存储的地址为null

2、常见的链表有:单链表、双链表、循环链表

  • 循环链表:和单链表区别只存在尾节点指针指向不同。单链表尾节点指针指向null,而循环链表尾节点指针指向该链表的其他节点。
  • 双链表:双链表数据结构相比单链表多了一个指向上一个节点的指针。结构如:prev+head + next --------prev+data+next --------prev+data+next-----prev+.....+prev+end+next ,其中prev记录上一个节点的地址

3、链表的特点。

基于链表的数据储存结构不连续的特点而言,插入、删除操作的执行效率比较高,涉及高频次的插入删除等操作可以使用链表。因其数据存储不连续,不能通过与数组类似的通过下标去查询数据。只能通过遍历链表去查询数据,因此查询效率较低。

二、链表的应用及常见问题:

1、链表的反转

package linkedlist;

public class reverserlist {
    /**
     * 单链表的反转
     *两种揭解法:1、迭代  2、递归
     */

    public static Node iterate(Node head){
        //迭代法
        Node prev = null,next;
        Node curr = head;

        while(curr != null){
            next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }
        return prev;
    }


    public static Node recursion(Node head){
        //递归法
        if(head == null || head.next == null){
            return head;
        }
        Node newhead = recursion(head.next);
        head=head.next.next;
        head.next=null;

        return newhead;
    }

    public static void main(String[] args) {
        Node head = new Node("1");
        Node n2 = new Node("2");
        Node n3 = new Node("3");
        Node n4 = new Node("4");
        Node n5 = new Node("5");
        Node n6 = new Node("6");

        head.setNext(n2);
        n2.setNext(n3);
        n3.setNext(n4);
        n4.setNext(n5);
        n5.setNext(n6);

        Node linklist = iterate(head);
        System.out.println(linklist);

        Node linklist1 = recursion(head);
        System.out.println(linklist1);
    }
}

 

2、是否存在环的检测

package linklisttest01;

public class isloop {

    /**
     * 快慢指针
     * @param head 头节点
     * @return 是否为环
     * */
    public static boolean isloops(Node head){

        if(head == null){
           return false;
        }
        Node p = head;
        Node q = head.next;

        while (p !=null && q!=null){
            p = p.next;
            q = q.next.next;
            if(q == null){
                return false;
            }
            else if(p == q){
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {

        Node head = new Node("head");
        Node h1 = new Node("hahaha");
        Node h2 = new Node("dadada");
        Node h3 = new Node("bababa");
        Node h4 = new Node("shasha");
        //Node h5 = new Node("kuakua");

        head.setNext(h1);
        h1.setNext(h2);
        h2.setNext(h3);
        h3.setNext(h4);
        h4.setNext(null);

        System.out.println(head.getNode());
        System.out.println(h1.getNode());
        System.out.println(h2.getNode());
        System.out.println(h3.getNode());
        System.out.println(h4.getNode());
        //System.out.println(h5.getNode());


        System.out.println("----------分割线----------");

        System.out.println(head.getData());
        System.out.println(h1.getData());
        System.out.println(h2.getData());
        System.out.println(h3.getData());
        System.out.println(h4.getData());
        //System.out.println(h5.getData());

        boolean isloop1 = isloops(head);
        System.out.println(isloop1);

    }
}

3、两个有序链表的合并

 

4、删除链表倒数第n个节点

5、求链表的中间节点

 

posted @ 2022-10-13 16:16  法卡萨多  阅读(247)  评论(0编辑  收藏  举报