自定义一个单向链表
链表
链表中存放着一个个Node,而每个Node又分为两部分,前一部分存放着Data,而后一部分存放着下一个节点的引用,这样一层层引用下去的一种结构。所以链表的结构决定了它的存储并不需要连续的存储空间。这样的链表访问头数据比较快,另外删除也比较快,但是查找靠后的数据稍微慢了点。
实现一个自定义链表
首先创建链表类
因为链表是由节点组成的,所以先实现节点
public class Node {
Node next;
T data;
public Node(T data, Node next) {
this.data = data;
this.next = next;
}
}
再完善链表类
public class MyLinkList
{
/*设计结点*/
//记录头节点
private Node head;
//记录元素个数
private int size;
public MyLinkList() {
//初始化头节点
this.head = new Node(0, null);
//初始化链表长度
this.size = 0;
}
private class Node {
Node next;//下一个结点
int data;//记录传入元素
/**
* 构建无参构造,创建对象
*/
public Node() {}
/**
* 构建有参构造,进行初始化
*/
public Node(int data, Node next) {
this.data = data;
this.next = next;
}
}
//这里开始放方法
}
构造方法类实现一个简单的增删查改
/*以下是对链表操作的各类方法*/
/**
* 返回此链表元素个数
* @return size
*/
public int getSize(){
return size;
}
/**
* 输出链表
*/
public void getList() {
//找到当前头节点
Node temp = head;
temp = temp.next;
System.out.print("[");
//循环判断输出非空链表
while (temp != null) {
System.out.print(temp.data);
temp = temp.next;
if(temp != null){
System.out.print(" ");
}
}
System.out.println("]");
}
/**
* 将指定的元素追加到此列表的末尾,返回true
* @param data 指定的元素
* @return true
*/
public boolean add(int data) {
//找到当前最后一个结点
Node temp = head;
while (temp.next != null)
{
temp = temp.next;
}
//创建新结点,保存元素data
Node newNode = new Node(data, null);
//当前最后一个结点指向新节点
temp.next = newNode;
//元素个数+1
size++;
return true;
}
/**
* 链表插入元素
*
* @param data 插入元素
* @param index 插入位置
*/
public void add(int index,int data) {
//判断插入位置是否合法
if (index < 0 || index > size) {
System.out.println("超出链表节点范围");
return;
}
//找到index位置的前一个结点
Node pre = head;
for (int i=0;i<=index-1 ;i++ )
{
pre = pre.next;
}
//找到index位置的结点
Node now = pre.next;
//创建新结点,并且新结点需要指向原来index位置的结点
Node newNode = new Node(data, null);
//原来index位置的前一个结点指向新节点
now.next = newNode;
//元素的个数+1
size++;
}
/**
* 将指定的元素追加到此列表的头部
* @param data 指定的元素
*/
public void addFirst(int data) {
//创建新结点,保存元素data
Node newHead = new Node(data, null);
//原来的头节点指向新结点
head.next = newHead;
//元素的个数+1
size++;
}
/**
* 将指定的元素追加到此列表的尾
* @param data 指定的元素
*/
public void addLast(int data) {
//找到当前最后一个结点
Node temp = head;
while (temp.next != null)
{
temp = temp.next;
}
//创建新结点,保存元素data
Node newNode = new Node(data, null);
//当前最后一个结点指向新节点
temp.next = newNode;
//元素个数+1
size++;
}
/**
* 移除链表所有元素
*/
public void clear() {
//创建一个新节点,并且使头节点指向该节点的空结点
Node newNode = new Node(0, null);
head.next = newNode.next;
//元素个数清零
size = 0;
}
/**
* 如果此列表包含指定的元素,则返回true
* @param data 指定的元素
* @return true
*/
public boolean contains(int data) {
//找到当前头节点
Node temp = head;
//循环判断指定元素是否存在
for (int i=0;i<=size ;i++ )
{
if (temp.data == data)
{
boolean isEmpty = (data == 0 && i == 0)?true:false;
if(isEmpty) {
return false;
}
return true;
}
temp = temp.next;
}
return false;
}
/**
* 检索,但不删除该列表的头(第一个元素)
*/
public void element() {
//找到当前头节点
Node temp = head;
//循环判断元素是否存在
for (int i=0;i<=size ;i++ )
{
boolean isEmpty = (temp.data == 0 && i == 0 && temp.next == null)||temp == null?true:false;
temp = temp.next;
if (isEmpty)
{
System.out.println("链表不存在或链表为空!");
break;
}else {
System.out.println("链表不为空,元素存在!");
break;
}
}
}
/**
* 返回列表中指定位置的元素
* @param index 指定的位置
* @return data
*/
public int get(int index) {
//判断插入位置是否合法
if (index < 0 || index > size) {
System.out.println("超出链表节点范围");
return 0;
}
//找到当前头节点
Node temp = head;
//循环到指定位置并返回保存元素
for (int i=0;i<=index ;i++ )
{
if (i == index)
{
System.out.println("已找到指定元素");
return temp.data;
}
temp = temp.next;
}
System.out.println("找不到指定元素");
return 0;
}
写一个测试类
class Test
{
public static void main(String[] args) {
MyLinkList myLinkList = new MyLinkList();
myLinkList.addFirst(250);
myLinkList.add(1314);
myLinkList.addLast(520);
myLinkList.getList();
System.out.println(myLinkList.getSize());
System.out.println(myLinkList. get(1));
System.out.println(myLinkList. get(250520));
}
}