常见数据结构之链表
一、链表基本定义及特点:
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、求链表的中间节点
当你试图去用自己的言语去讲清一些事物时,你会明白对此事物的理解是融会贯通还是一知半解