Java数据结构——线性单链表的实现
一、描述
线性表的链式存储结构的特点:用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的)。因此它没有顺序存储结构所具有的弱点(顺序存储结构插入数据或删除数据都要移动大量的数据),但同时也失去了顺序表可随机存取的优点。
单链表的组成为:数据信息和指向下一个节点的指针。
二、源码
2.1 节点信息Node.java
package com.yds.list;
public class Node<T> {
protected Node next;
protected T data;
public Node(T data){
this.data = data;
}
}
上述T为泛型
2.2 单链表的基本操作LinkList.java
package com.yds.list;
public class LinkList<T> {
public Node head;
private int position;
private int size = 0;
public LinkList(){
this.head = null;
}
/**
* 删除头结点并返回该节点
* @return
*/
public Node deleteHeadNode(){
Node tempNode = head;
head = head.next;
size--;
return tempNode;
}
/**
* 根据下标删除指定节点
* @param index
*/
public void delete(int index){
Node preNode = head;
Node tempNode = head;
if(index<0||index>size-1){
System.out.println("数组下标越界,删除失败");
return;
}else{
while(position!=index){
preNode = tempNode;
tempNode = tempNode.next;
position++;
}
preNode.next = tempNode.next;
}
position=0;
size--;
}
public int length(){
return size;
}
/**
* 通过位置来查找节点信息
* @param index
* @return
*/
public T findByPositon(int index){
T data;
Node current = head;
if(index>=0&&index<size){
while(position!=index){
current = current.next;
position++;
}
data = (T) current.data;
}else{
throw new IndexOutOfBoundsException("超出链表长度");
}
position = 0;
return data;
}
/**
* 根据数据查询该数据在链表里的位置
* @param data 需查找的数据
* @return -1到size-1;-1表示未找到,0到size-1为数据在链表里的位置
*/
public int findByData(T data){
int temp = position;
Node tempNode = head;
while(data!=tempNode.data&&position<size-1){
tempNode = tempNode.next;
position++;
}
if(data==tempNode.data)
temp = position;
else{
System.out.println("未找到");
temp = -1;
}
position = 0;
return temp;
}
/**
* 在index之前插入节点
* @param index 插入的位置
* @param data 待插入的数据
*/
public void insert(int index,T data){
Node node = new Node(data);
Node current = head;
Node preNode = head;
if(index<0&&index>size){
throw new IndexOutOfBoundsException("index 位置不合法");
}else{
while(position!=index){
preNode = current;
current = current.next;
position++;
}
preNode.next = node;
node.next = current;
size++;
position=0;
}
}
/**
* 从尾部插入数据
* @param data
*/
public void addFromTail(T data){
Node<T> node = new Node<T>(data);
Node tempNode = head;
if(head!=null){
while(position!=size-1){
tempNode = tempNode.next;
position++;
}
node.next = tempNode.next;
tempNode.next = node;
}else{
node.next = head;
head = node;
}
size++;
position = 0;
}
/**
* 头插法
* @param data
*/
public void addFromHead(T data){
Node node = new Node(data);
node.next = head;
head = node;
size++;
}
}
2.3 Main函数展示JavaMain.java
package com.yds.list;
public class JavaMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
LinkList<Integer>listB = new LinkList<Integer>();
LinkList listA = new LinkList();
int[] la = {3,5,8,11};
int[] lb = {2,6,8,9,11,15,20};
System.out.println("-------尾插法---------");
for (int i = 0; i < la.length; i++) {
listA.addFromTail(la[i]);
}
for (int i = 0; i < listA.length(); i++) {
System.out.println(listA.findByPositon(i));
}
System.out.println("---------头插法----------");
for (int i = 0; i < lb.length; i++) {
listB.addFromHead(lb[i]);
}
for (int i = 0; i < listB.length(); i++) {
System.out.println(listB.findByPositon(i));
}
System.out.println("-------------------");
System.out.println("根据数据查找位置:"+listB.findByData(2));
System.out.println("根据位置查找数据:"+listB.findByPositon(listB.findByData(2)));
System.out.println("获取链表listB的长度:"+listB.length());
//因为listA的数据类型为泛型(T),所以可以插入任意类型的数据,而listB只能插入整型(integer)
listA.insert(2, "ye");
System.out.println("插入数据:"+listA.findByPositon(2));
System.out.println("-------------------");
listB.delete(6);
for (int i = 0; i < listB.length(); i++) {
System.out.println(listB.findByPositon(i));
}
}
}
三、结果截图