链式存储结构的线性表 简称为链表。是采用一组地址任意的存储单元存放线性表中的元素数据。
它需要在每一个数据元素里保存一个引用下一个数据元素的引用 --- 指针。单链表 --- 每个节点只保留一个引用, 该引用指向当前节点的下一个节点, 没有引用指向头节点, 尾节点的next引用为null。
建立的方法 :
1.头插法 : 该方法从一个空表开始, 不断创建新节点,将数据元素存入节点的data域中, 然后不断地以新节点为头节点,并让新节点指向原来的头节点。
2.尾插法 : 新节点插入当前链表的表尾上, 因此需要为链表定义一个引用变量来保存链表的最后一个节点。
查找:(1) 找第index个元素:从header节点依次向下在单链表中找第index个节点。 算法:以head为头, current为当前节点(初始时current从header起)0 为头节点序号, i 为计数器 则counter依次下移寻找节点, 并使i 同时递增记录节点序号, 直到返回指定节点。
(2) 找element元素:找到是否又等于给定element值的节点 有返回相应的索引 ,无返回-1。
插入:element的新节点插入到第index个节点的位置上, 找到index - 1的节点, 生成一个数据域为element的newNode
使得index -1处的节点的next域指向新的节点, 新节点的next指向原来的index处的节点。
删除:index个节点删除, 先找到引用它的index - 1节点, 然后让index - 1的next指向原来的index + 1节点 ,释放index处的节点。
参考代码:
1.头插法 : 该方法从一个空表开始, 不断创建新节点,将数据元素存入节点的data域中, 然后不断地以新节点为头节点,并让新节点指向原来的头节点。
2.尾插法 : 新节点插入当前链表的表尾上, 因此需要为链表定义一个引用变量来保存链表的最后一个节点。
查找:(1) 找第index个元素:从header节点依次向下在单链表中找第index个节点。 算法:以head为头, current为当前节点(初始时current从header起)0 为头节点序号, i 为计数器 则counter依次下移寻找节点, 并使i 同时递增记录节点序号, 直到返回指定节点。
(2) 找element元素:找到是否又等于给定element值的节点 有返回相应的索引 ,无返回-1。
插入:element的新节点插入到第index个节点的位置上, 找到index - 1的节点, 生成一个数据域为element的newNode
使得index -1处的节点的next域指向新的节点, 新节点的next指向原来的index处的节点。
删除:index个节点删除, 先找到引用它的index - 1节点, 然后让index - 1的next指向原来的index + 1节点 ,释放index处的节点。
参考代码:
public class LinkList<T> {
//定义一个节点类
private class Node{
//保存数据
private T data;
//下一个节点域
private Node next;
public Node(){
}
public Node(T data, Node next){
this.data = data;
this.next = next;
}
}
//保存头节点 和 尾节点
private Node header;
private Node tail;//trailer prev域 和 next域 -- 引用域
//链表中的节点数
private int size;
//创建空链表
public LinkList(){
header = null;
tail = null;
}
//根据指定元素创建链表
public LinkList(T element){
header = new Node(element, null);//创建每一个元素是以节点的形式出现的
tail = header;
size ++;
}
//返回链表节点的长度
public int length(){
return size;
}
//查找1 回去index处的节点
public T get(int index){
return getNodeByIndex(index).data;
}
//根据索引获取节点
private Node getNodeByIndex(int index) {
if(index < 0 || index > size -1){
throw new IndexOutOfBoundsException("线性表越界");
}
Node current = header;
for(int i = 0; i < size && current != null; i ++, current = current.next){//依次向下寻找节点
if(i == index){
return current;
}
}
return null;
}
//查找指定的element
public int locate(T element){
Node current = header;
for(int i = 0; i < size && current != null; i ++, current = current.next){//依次向下寻找节点
if(current.data == element){
return i;
}
}
return -1;
}
//插入数据
public void insert(T element, int index){
if(index < 0 || index > size){
throw new IndexOutOfBoundsException("线性表越界");
}
if(header == null){
add(element);
}
else{
if(index == 0){
addAtHeader(element);
}
else{
Node preNode = getNodeByIndex(index - 1);
preNode.next = new Node(element, preNode.next);
size ++;
}
}
}
//头插法
public void addAtHeader(T element) {
//作为一个新的头
header = new Node(element, header);
if(tail == null){
tail = header;
}
size ++;
}
//尾插法
public void add(T element){
//判断是不是空
if(header == null){
header = new Node(element, null);
tail = header;
}
else{
Node newNode = new Node(element, null);
tail.next = newNode;
tail = newNode;
}
size ++;
}
//删除数据
public T delete(int index){
if(index < 0 || index > size -1){
throw new IndexOutOfBoundsException("线性表越界");
}
Node delNode = null;
//被删除的是头节点
if(index == 0){
header = delNode;
header = header.next;
}
else{
Node preNode = getNodeByIndex(index - 1);
delNode = preNode.next;
preNode = delNode.next;
//被删除节点的next引用赋值为null
delNode.next = null;
}
size --;
return delNode.data;
}
//判断是否为空
public boolean empty(){
return size == 0;
}
//清空列表
public void clear(){
header = null;
tail = null;
size = 0;
}
public String toString(){
if(size == 0){
return "[]";
}
else{
StringBuffer sb = new StringBuffer("[");
for(Node current = header; current != null; current = current.next){
sb.append(current.data.toString() + ", ");//这里, 后面的空格很重要, 否则输出时可能出错
}
int len = sb.length();
return sb.delete(len - 2, len).append("]").toString();
}
}
}
测试部分:
public static void main(String[] args) {
LinkList<Integer> llist = new LinkList<Integer>();
llist.insert(1, 0);
llist.add(2);//尾插法
llist.add(3);
System.out.println(llist);
System.out.println("2在中的位置:" + llist.locate(2));
llist.addAtHeader(4);
System.out.println(llist);
System.out.println("第2个位置的元素是:" + llist.get(2));
}
参考:《疯狂java突破程序员的基本功的16课》
以上就是这篇的内容,如果存在错误的地方或有可以优化的地方,请您指出,谢谢!