package com.example.mydemo.myapi; /** * @Author zmz * @Class_Name:LinkNode * @Create_Date:2019/6/26 * @Des: 自定义双向链表结构 */ public class LinkdNode { //根节点 private Node mRootNode; //要添加的节点 private Node mNextNode; //尾部节点 private Node mLastNode; //链表大小 private int mSize = 0; /** * 添加数据 * * @param data */ public void addNode(String data) { mNextNode = new Node(data); //根节点如果为null那么就将新增的节点添加到根节点中 if (0 == mSize) { mRootNode = mNextNode; mLastNode = mNextNode; } else { //如果存在根节点,那么进行递归调用类中的方法进行添加节点 mNextNode.mPrevious = mLastNode; mLastNode.mNext = mNextNode;// 添加到最后一个节点后面 mLastNode = mNextNode;// 更新最后一个节点 } mSize++; } /** * 头部添加节点 * * @param data */ public void addHeadNode(String data) { //创建新节点 Node newNode = new Node(data); //如果根节点为空,就把新创建的节点赋值给根节点 if (mRootNode == null) { mRootNode = newNode; mRootNode.mPrevious = null; mLastNode = newNode; } else {//根节点不为空,则在根节点的左边添加节点 //根节点赋值给新的对象 Node oldNode = mRootNode; //根节点重新赋值 mRootNode = newNode; //新节点的Next指向以前的根节点 mRootNode.mNext = oldNode; oldNode.mPrevious = mRootNode; } mSize++; } /** * 在指定位置添加节点 * * @param index * @param data */ public void addIndexNode(int index, String data) { if (index >= mSize) { throw new RuntimeException("插入越界异常"); } //头部插入节点 if (0 == index) { addHeadNode(data); return; } //尾部插入数据 if (index == mSize - 1) { addNode(data); return; } //创建新节点 Node newNode = new Node(data); Node insertNode = mRootNode; for (int i = 0; i < index - 1; i++) { //找到要插入的节点的上一个节点 insertNode = insertNode.mNext; } insertNode.mNext.mPrevious = newNode; newNode.mNext = insertNode.mNext; newNode.mPrevious = insertNode; insertNode.mNext = newNode; mSize++; } /** * 根据角标替换节点 * * @param index * @param data */ public void replaceNode(int index, String data) { if (index >= mSize) { throw new RuntimeException("下标越界异常"); } //创建要插入的节点 Node newNode = new Node(data); if (0 == index) { newNode.mNext = mRootNode.mNext; mRootNode = newNode; return; } Node replaceNode = mRootNode; for (int i = 0; i < index - 1; i++) { //找到要替换的节点的上一个节点 replaceNode = replaceNode.mNext; } newNode.mNext = replaceNode.mNext.mNext; newNode.mPrevious = replaceNode; replaceNode.mNext = null; replaceNode.mNext = newNode; if (index == mSize - 1) { mLastNode = newNode; } } /** * 根据下标删除节点 * * @param index */ public void deleteNode(int index) { if (index >= mSize) { throw new RuntimeException("下标越界异常"); } //如果是第一个节点 if (index == 0) { mRootNode = mRootNode.mNext; mRootNode.mPrevious = null; return; } //创建新节点 Node deleteNode = mRootNode; for (int i = 0; i < index - 1; i++) { //找到要删除的节点的上一个节点 deleteNode = deleteNode.mNext; } //如果不是最后一个节点 if (index != mSize - 1) { deleteNode.mNext = deleteNode.mNext.mNext; } else { deleteNode.mNext = null; mLastNode = deleteNode; } mSize--; } /** * 删除一个节点 * * @param data */ public void deleteNode(String data) { //如果包含这个节点在进行删除操作 if (contains(data)) { //根节点是这个节点--改变根节点的引用 if (mRootNode.mData.equals(data)) { Node currentNode = mRootNode.mNext; mRootNode = currentNode.mNext; mRootNode.mPrevious = currentNode.mPrevious; } else { //不是根节点--递归的查找 改变引用 Node deleteNode = mRootNode; for (int i = 0; i < mSize - 1; i++) { //找到要删除的节点的上一个节点 deleteNode = deleteNode.mNext; if (data.equals(deleteNode.mNext.mData)) { //如果是第一个节点 if (i == 0) { mRootNode = mRootNode.mNext; mRootNode.mPrevious = null; return; } //如果不是最后一个节点 if (i != mSize - 1) { deleteNode.mNext = deleteNode.mNext.mNext; } else { deleteNode.mNext = null; mLastNode = deleteNode; } deleteNode(i); return; } } } mSize--; } } /** * 根据下标获取节点数据 * * @param index * @return */ public String getNode(int index) { if (index >= mSize) { throw new RuntimeException("下标越界异常"); } Node getNode = mRootNode; for (int i = 0; i > index - 1; i++) { getNode = getNode.mNext; } return getNode.mNext.mData; } /** * 是否包含指定节点数据 * * @param data * @return */ public boolean contains(String data) { //根节点是该节点 直接返回 if (mRootNode.mData.equals(data)) { return true; } else { //如果根节点不是,那么继续向下找! Node containsNode = mRootNode; for (int i = 0; i > mSize - 1; i++) { containsNode = containsNode.mNext; if (data.equals(containsNode.mNext.mData)) { return true; } } return false; } } /** * 获取链表大小 * * @return */ public int getSize() { return mSize; } /** * 打印所有节点数据 */ public void printNode() { if (mRootNode != null) { mRootNode.printNode(); } } /** * 链表节点类 */ public static class Node { //上一个节点引用 private Node mPrevious; //当前节点数据 private String mData; //下一个节点的引用 private Node mNext; public Node(String data) { mData = data; } } }
优化版自定义双向链表,可以和LinkedList比较一下速度(稍微逊色一点)
最新推荐文章于 2024-04-21 18:38:32 发布