首先链表是以节点的方式存储数据的,每个节点包含数据域(data),节点域(next),链表的每个节点在计算机中存储的位置是不连续的和随机的,优点就是数据的插入和删除比较好,而查找数据效率不是太好(因为链表无法像静态数据一样随机读取数据,必须按照顺序找到对应的数据为止)。
单向链表就像是火车,所有的节点串联成一列,而且指针所指的方向一样,也就是链表中每个节点除了存储原本的数据,还有存储下一个节点的存储地址。如下图所示:
节点类的代码实现
class SingleNode {
public Object object; //节点数据
public SingleNode next; //指向下一个节点
public SingleNode() {
}
public SingleNode(Object object, SingleNode next) {
this.object = object;
this.next = next;
}
}
2.2.单向链表实现(增加,删除,修改,查看)数据
/**
* 单链表的实现
*/
public class SingleLinkList {
private SingleNode first; //定义头结点
private SingleNode last; //定义尾节点
private int size; //定义链表的节点数
/**
* 判断链表是否为空
* @return
*/
public boolean isEmpty() {
return first == null;
}
/**
* 在链表的头部和尾部添加元素
* 思路分析:当链表为空时,就相当于在链表的头部添加数据,所以把新添加的节点赋值给头结点(尾节点),
* 当链表不为空时,就相当于于在链表的尾部添加数据,这时候我们就是把尾部的指针指向新添加的节点(即last.next=node),然后把新添加的节点赋值到
* 最后节点 (即last=node)
*/
public void add(Object object) {
SingleNode node = new SingleNode(object, null);
if (isEmpty()) {
first = node;
} else {
last.next = node;
}
last = node;
size++;
}
/**
* 在指定的节点增加元素
* 思路分析:首先我们需要判断添加的位置是否满足条件(index>0 && index<size),然后我们需要找到指定索引位置的元素和它的上一个位置的元素,所以用到
* 两个指针来记录索引位置的元素和它上一个位置的元素,最后把 (before.next=node,node.next=temp),这就相当于把before指向node,node指向当前节点(temp)即可。
* @param index
* @param object
*/
public void addElement(int index, Object object) {
SingleNode node = new SingleNode(object, null);
if (index > 0 && index < size) {
SingleNode temp = first;
SingleNode before = null;
for (int i = 0; i < index; i++) {
before = temp;
temp = temp.next;
}
before.next = node;
node.next = temp;
size++;
}
}
/**
* 展示链表中的节点元素
*/
public void show() {
if (!isEmpty()) {
SingleNode current = first;
while (current != null) {
System.out.println(current.object);
current = current.next;
}
}
}
/**
* 获得指定节点的元素
* 思路分析:定义一个指针,循环到指定位置,把元素取出即可
* @param index
* @return
*/
public Object get(int index) {
if (index > 0 && index < size) {
if (!isEmpty()) {
SingleNode temp = first;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
return temp.object;
}
}
return null;
}
/**
* 删除指定节点的元素
* 思路分析:需要定义两个指针来记录要删除的节点和要删除节点的上一个节点,然后 把before.next=temp.next即可。
* @param index
*/
public void remove(int index) {
if (index > 0 && index < size) {
if (!isEmpty()) {
SingleNode temp = first;
SingleNode beforeTemp = null;
for (int i = 0; i < index; i++) {
beforeTemp = temp;
temp = temp.next;
}
beforeTemp.next = temp.next;
}
}
}
/**
* 修改指定节点的指定元素
*
* @param index
* @param object
*/
public void update(int index, Object object) {
if (index > 0 && index < size) {
if (!isEmpty()) {
SingleNode temp = first;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
temp.object = object;
}
}
}
/**
* 实现链表的反向打印
* 思路分析:利用栈先进后出的特点,首先把元素放到栈中,然后再取出,即可。
*/
public void rePrint() {
Stack<SingleNode> stack = new Stack<SingleNode>();
if (!isEmpty()) {
SingleNode current = first;
while (current != null) {
stack.push(current);
current = current.next;
}
while (stack.size() > 0) {
System.out.println(stack.pop().object);
}
}
}
/**
* 将单链表反转
*/
public void reversetList() {
SingleNode current = first;
SingleNode before = null;
while (current != null) {
last = before;
before = current;
current = current.next;
before.next = last;
}
current = before;
while (current != null) {
System.out.println(current.object);
current = current.next;
}
}
原文:https://www.cnblogs.com/xiaofuzi123456/p/12676819.html