数据结构与算法(java)——链表
来源:互联网 发布:常用的nosql数据库 编辑:程序博客网 时间:2024/06/05 06:35
- 单链表:是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,结点的构成:元素(数据元素的映像) + 指针(指示后继元素的存放位置)。
代码实现:
public class LinkList { // 头结点 private Node head; public LinkList() { head = new Node(); } /** * 插入一个结点,在头结点后进行插入 * * @param data */ public void insertAtHead(long data) { Node node = new Node(data); node.next = head.next; head.next = node; } /** * 删除一个结点,在头结点后进行删除 * * @return */ public Node deleteAtHead() { Node tmp = head.next; head.next = tmp.next; return tmp; } /** * 显示所有数据 */ public void displayAll() { Node curNode = head.next; while (curNode != null) { curNode.display(); curNode = curNode.next; } System.out.println(); } /** * 查找方法,根据数据域查找 * * @param data * @return */ public Node find(long data) { Node curNode = head.next; while (curNode.data != data) { if (curNode.next == null) { return null; } curNode = curNode.next; } return curNode; } /** * 删除方法,根据数据域进行删除 * * @param data * @return */ public Node delete(long data) { Node curNode = head.next; Node preNode = head.next; while (curNode.data != data) { if (curNode.next == null) { return null; } preNode = curNode; curNode = curNode.next; } if (curNode == head.next) { head.next = curNode.next; } else { preNode.next = curNode.next; } return curNode; }}
- 双端链表:将单链表的终端结点的指针端指向头结点,使头尾相接形成一个环称为单循环链表,简称循环链表(circular linked list)或双端链表。
代码实现:
public class CircularLindedList { // 头结点 private Node head; // 尾结点 private Node rear; public CircularLindedList() {//构造一个空的循环单链表 head = new Node(); rear = head; head.next = rear; } /** * 插入一个结点,在头结点后进行插入 * * @param data */ public void insertAtHead(long data) { Node node = new Node(data); if(isEmpty()){ node.next = head; head.next = node; rear = node; } else { node.next = head.next; head.next = node; } } /** * 插入一个结点,在尾结点后插入 * * @param data */ public void insertAtRear(long data) { Node node = new Node(data); if(isEmpty()){ node.next = head; head.next = node; } else { node.next = head; rear.next = node; } rear = node; } /** * 删除一个结点,在头结点后进行删除 * * @return */ public Node deleteAtHead() { if(isEmpty()){ return null; } Node tmp = head.next; head.next = tmp.next; return tmp; } /** * 显示所有数据 */ public void displayAll() { Node curNode = head.next; while (curNode != head) { curNode.display(); curNode = curNode.next; } System.out.println(); } /** * 查找方法,根据数据域查找 * * @param data * @return */ public Node find(long data) { if(isEmpty()){ return null; } Node curNode = head.next; while (curNode.data != data) { if (curNode.next == head) {//遍历完了整个单链表 return null;//没有找到要查询的数据 } curNode = curNode.next; } return curNode; } /** * 删除方法,根据数据域进行删除 * * @param data * @return */ public Node delete(long data) { if(isEmpty()){ return null; } Node curNode = head.next; Node preNode = head.next; while (curNode.data != data) { if (curNode.next == head) { return null;//没有找到要删除的数据 } preNode = curNode; curNode = curNode.next; } if (curNode == head.next) { head.next = curNode.next; } else { preNode.next = curNode.next; } return curNode; } /** * 是否为空 * * @return */ public boolean isEmpty() { return head.next == head; } /** * 获得尾结点 * @return */ public Node getRear() { return rear; }}
- 双向链表:每个结点有两个指针域,分别指向它的前驱和后继结点;循环双向链表 即尾结点的后继指针域指向头结点,头结点的前驱指针域指向尾结点,形成一个闭环。
循环双向链表:
代码实现:
/** * 循环双向链表 * @author kushanmao * @date 2017-7-2 */public class CircularDoubleLinkedList { // 头结点 private DoubleNode head; // 尾结点 private DoubleNode rear; public CircularDoubleLinkedList() {// 构造空的循环双向链表 head = new DoubleNode(); rear = head; head.next = head; head.previous = head; } /** * 插入一个结点,在头结点后进行插入 * * @param data */ public void insertAtHead(long data) { DoubleNode node = new DoubleNode(data); if (isEmpty()) { node.previous = head; node.next = head; head.previous = node; head.next = node; rear = node; } else { node.previous = head;// 1、将前驱指向头结点 node.next = head.next;// 2、将后继指向head.next head.next.previous = node;// 3、将head.next的前驱指向node head.next = node;// 4、将头结点的后继指向node } } /** * 插入一个结点,在尾结点后插入 * * @param data */ public void insertAtRear(long data) { DoubleNode node = new DoubleNode(data); if (isEmpty()) { node.previous = head; node.next = head; head.previous = node; head.next = node; } else { node.previous = rear; node.next = rear.next;// node.next = head; rear.next.previous = node;// head.previous = node; rear.next = node; } rear = node; } /** * 删除一个结点,在头结点后进行删除 * * @return */ public DoubleNode deleteAtHead() { if (isEmpty()) { return null; } DoubleNode tmp = head.next; head.next = tmp.next; tmp.next.previous = head; return tmp; } /** * 删除一个结点,从尾部进行删除 * * @return */ public DoubleNode deleteAtRear() { DoubleNode node = rear; rear.previous.next = head; head.previous = rear.previous; rear = rear.previous; return node; } /** * 显示所有数据 */ public void displayAll() { DoubleNode curNode = head.next; while (curNode != head) { curNode.display(); curNode = curNode.next; } System.out.println(); } /** * 查找方法,根据数据域查找 * * @param data * @return */ public DoubleNode find(long data) { DoubleNode curNode = head.next; while (curNode.data != data) { if (curNode.next == head) { return null;// 遍历完了整个链表,没有找到要查询的数据 } curNode = curNode.next; } return curNode; } /** * 删除方法,根据数据域进行删除 * * @param data * @return */ public DoubleNode delete(long data) { DoubleNode curNode = head.next; while (curNode.data != data) { if (curNode.next == head) { return null; } curNode = curNode.next; } curNode.previous.next = curNode.next; curNode.next.previous = curNode.previous; return curNode; } /** * 是否为空 * * @return */ public boolean isEmpty() { return head.next == head; } /** * 获取尾结点 * * @return */ public DoubleNode getRear() { return rear; }}
总结:
- 在这里的链表都是有头结点的;
- 由于链表的查找都要遍历整个链表,所以需要大量查询操作的情况一般不使用链表,但是链表的增删是很方便的,增删操作越频繁效率优势就越明显;
- 双向链表的的空间占用相较于单链表会大些(要保存两个指针),但是在时间性能上优于单链表,效率较高
阅读全文
2 1
- 数据结构与算法(java)——链表
- 《java数据结构与算法》——数组
- 数据结构与算法——选择排序(Java实现)
- 数据结构与算法——插入排序(Java实现)
- 数据结构与算法——希尔排序(Java实现)
- 数据结构与算法(java)——栈和队列
- 数据结构与算法—常用数据结构及其Java实现
- 【数据结构与算法】汉诺塔算法——java递归实现
- 读书笔记:数据结构与算法分析(Java语言描述)——数据结构概论
- 数据结构与算法Java版——栈与队
- java数据结构与算法
- Java数据结构与算法
- 《JAVA数据结构与算法》
- java 数据结构与算法
- Java数据结构与算法
- java 数据结构与算法
- Java数据结构与算法
- Java数据结构与算法
- 使用WebApplicationContextUtils.getWebApplicationContext(ServletContext cn)获取WebApplicationContext为null
- jquery datatable调用.clear().draw()方法后不能清空表格数据
- 我的第一次h5 五子棋游戏作品
- google的glog日志管理
- 剑指offer面试题15 链表中倒数第K个结点
- 数据结构与算法(java)——链表
- 频道循环,每个子栏目下,自动加广告位
- 如何给100亿个数字排序?
- Linux更换默认软件源
- javascript之面向对象编程续
- Unity3d 序列目标点的移动
- 【剑指offer】题32:从1到n整数中1出现的次数
- spring 整合 redis,以及spring的RedisTemplate如何使用
- Python中join的简单用法