package com.dby.link;
/**
* Created by suzunshou on 2016/4/11.
* 链表的元素不能随机访问
* 元素前面和后面不会出现多个元素相连的情况
* 元素相互依赖,串联而成
* 链表只有一个表头
*/
public class LinkedList {
//结点类
private class Node {
//数据
private Object data;
//下一个结点的地址
private Node next = null;
public Node(Object data) {
this.data = data;
}
}
private Node first = null;
private Node last = null;
private int size;
//在首部插入结点
public void insertFirst(Object data) {
//创建一个新结点
Node newNode = new Node(data);
//结点指向原来的first结点
newNode.next = first;
//将结点赋值给first结点
first = newNode;
Node p = first;
Node q = null;
//遍历查找最后一个结点
while (p != null) {
q = p;
p = p.next;
}
//将结点放到尾结点
last = q;
size++;
}
//链表尾部插入结点
public void insertLast(Object data) {
//新结点
Node newNode = new Node(data);
//空链表的话,新结点放first
if (first == null) {
first = newNode;
} else {
Node p = first;
Node q = null;
//遍历查找最后一个结点
while (p != null) {
q = p;
p = p.next;
}
//将结点放到尾结点
q.next = newNode;
last = newNode;
}
size++;
}
//插入结点到某个位置
public void insert(Object data, int index) {
//新结点
Node newNode = new Node(data);
//空链表
if (first == null) {
first = newNode;
return;
}
//只有一个结点
if (index - 1 == 0) {
newNode.next = first;
first = newNode;
return;
}
//普通情况
Node curr = first;
int count = 0;
//遍历找到索引处的结点
while (curr.next != null && count < index - 2) {
curr = curr.next;
count++;
}
//插入结点,把前一个结点和后一个结点断开,两端接上新结点
if (count == index - 2) {
newNode.next = curr.next;
curr.next = newNode;
}
}
//查找所有结点
public void findAll() {
//空结点
if (first == null)
return;
//遍历结点
Node cur = first;
while (cur != null) {
System.out.print(cur.data + "->");
cur = cur.next;
}
System.out.println("\n");
}
//反转链表
public void reverse() {
//空链表
if (first == null) {
return;
}
Node next_node, curr_node;
//第二个结点
curr_node = first.next;
//断开第一第二个结点
first.next = null;
//反转相当于每次都findOne+insertFirst
while (curr_node != null) {
//第三个结点
next_node = curr_node.next;
//把第一个结点接到第二个结点的另一端
curr_node.next = first;
//把第二个结点变成新的第一个结点
first = curr_node;
//移动到下一个结点
curr_node = next_node;
}
}
//删除首结点
public void deleteFirst() {
//空结点
if (first == null)
return;
//指针移向first结点指向的结点的下一个结点
first = first.next;
size--;
}
//删除尾结点
public void deleteLast() {
//空链表
if (first == null)
return;
//只有一个结点
if (first.next == null) {
first = null;
size--;
} else {
//多个结点
Node p = first;
Node q = null;
//遍历结点,找出倒数第2个结点
while (p.next != null) {
q = p;
p = p.next;
}
//删除最后一个结点
q.next = null;
size--;
}
}
//根据数据查找结点
public Node findOne(Object data) {
//空链表
if (first == null)
return null;
//令当前结点为first结点
Node cur = first;
//遍历结点
while (cur != null) {
//查找到了,返回
if (cur.data.equals(data)) {
return cur;
} else {
//否则,继续查找下一个结点
cur = cur.next;
}
}
return null;
}
//根据索引找出结点
public Node findByIndex(int index) {
if (index - 1 > size) {
} else {
Node curr = first;
for (int i = 1; i < index; i++) {
curr = curr.next;
}
return curr;
}
return null;
}
//是否为空
public boolean isEmpty() {
return (size == 0);
}
//删除某一个结点
public void remove(Object data) {
//空链表
if (first == null) {
return;
}
//单结点链表
if (first.data.equals(data)) {
first = first.next;
size--;
} else {
//前一个结点
Node prev = first;
//中间结点
Node cur = first.next;
while (cur != null) {
if (cur.data.equals(data)) {
//后一个结点接到前一个结点,顶替中间结点
prev.next = cur.next;
size--;
}
//否则,前一个结点移动到下一个结点
prev = cur;
//中间结点移动到下一个结点
cur = cur.next;
}
}
}
//根据索引删除结点
public void removeByIndex(int index) {
//空链表
if (first == null) {
return;
}
//单结点
Node curr = first;
int count = 0;
if (index - 1 == 0) {
first = first.next;
return;
}
//普通情况,找到结点
while (curr.next != null && count < index - 2) {
curr = curr.next;
count++;
}
//删除结点
if (count == index - 2 && curr.next != null) {
Node delete_node = curr.next;
curr.next = delete_node.next;
delete_node = null;
}
size--;
}
public static void main(String[] args) {
LinkedList ll = new LinkedList();
for (int i = 1; i < 8; i++) {
ll.insertLast(i);
}
ll.removeByIndex(2);
ll.removeByIndex(4);
ll.findAll();
System.out.println(ll.findByIndex((ll.size + 1) / 2).data);
ll.insert(2,2);
ll.insertFirst(0);
System.out.println(ll.findOne(2).data);
ll.findAll();
}
}
数据结构之链表
最新推荐文章于 2024-06-24 19:19:56 发布