线性表的数据结构图:
链表简介:
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列节点组成,这些节点不必在内存中相连。每个节点由数据部分Data和链部分Next,Next指向下一个节点,这样当添加或者删除时,只需要改变相关节点的Next的指向,效率很高。
链表的实现还有其它的方式,常见的有循环单链表,双向链表,循环双向链表。 循环单链表 主要是链表的最后一个节点指向第一个节点,整体构成一个链环。 双向链表 主要是节点中包含两个指针部分,一个指向前驱元,一个指向后继元,JDK中LinkedList集合类的实现就是双向链表。** 循环双向链表** 是最后一个节点指向第一个节点。
操作的源码如下:
package com.wpao.data;
public class NodeTest {
/**
* @param args
*/
public static void main(String[] args) {
NodeTest nodetest = new NodeTest ();
Node<Students> head = null;
Node<Students> tail = null;
System.out.println("原链表:");
head = nodetest.constructNode(head);
Node<Students> remove = nodetest.remove(head,0);
nodetest.eachNode(remove);
Node<Students> get = nodetest.get(head, 0);
System.out.println("******"+((get!=null) ? get.item.toString():"不存在"));
/*
System.out.println("反转后:");
head = nodetest.fanzhuanNode(head);
nodetest.eachNode(head);
System.out.println("倒序便利:");
nodetest.reverseNode(head);
System.out.println("顺序便利:");
nodetest.eachNode(head);
*/
}
/**
* 删除特定元素:
* @param head
* @param i
* @return
*/
public Node<Students> remove(Node<Students> head,int i){
Node<Students> curr = null;
Node<Students> previous = null;
if(i<1){
System.out.println(" 该元素不存在,当前下标:"+i+",设定第一个元素为1.");
}
curr = head;
int j = 1;
while(curr != null){
if(i==j){
if(previous==null){
return null;
}
previous.next = curr.next;
return head;
}
previous = curr;
curr = curr.next;
j+=1;
}
return head;
}
/**
* 获取特定元素:
* @param head
* @param i
* @return
*/
public Node<Students> get(Node<Students> head,int i){
Node<Students> curr = null;
if(i<1){
System.out.println(" 该元素不存在,当前下标:"+i+",设定第一个元素为1.");
}
curr = head;
int j = 1;
while(curr != null){
if(i==j){
return curr;
}
curr = curr.next;
j+=1;
}
return null;
}
/**
* 将链表的顺序进行反转:逐一改变相邻两节点之间的关系,返回之前的尾节点处理;
* 注意点:对象的引用是同一个内存区域,一个引用修改,另一个引用也发生修改;
* @param head
* @return
*/
public Node<Students> fanzhuanNode (Node<Students> head){
Node<Students> curr = head;//i节点;
Node<Students> next = null;//i+1点;
Node<Students> previous = null;//i-1点;
while(curr != null){
next = curr.next;
if (next ==null){
curr.next = previous;
return curr;
}
curr.next = previous;
previous = curr;
curr = next;
}
return null;
}
/**
* 倒序便利:采用递归的思想,逐步取出最后一个元素,后输出;
* @param head
*/
public void reverseNode (Node<Students> head){
if(head!=null){
reverseNode(head.next);
System.out.println(" "+head.item);
}
}
/**
* 顺序便利:输出当前元素,然后将当前元素的指向为下一个元素;
* @param head 头节点:
*/
public void eachNode(Node<Students> head){
if(head==null){
System.out.println(" 链表为空!");
}
Node<Students> curr = head;
while(curr != null){
System.out.println(" "+curr.item);
curr = curr.next;
}
}
/**
* 构造链表:
* @param head 头节点;
* @param tail 尾节点;
*/
public Node<Students> constructNode(Node<Students> head){
//构造第一个节点:
head = new Node(new Students(1,"first1"));
Node<Students> tail = head;
//构造第二个节点:
tail.next = new Node(new Students(2,"first2"));
tail = tail.next;
for(int i=3;i<10;i++){
tail.next = new Node(new Students(i,"first"+i));
tail = tail.next;
}
return head;
}
}
/**
* 节点声明:
* @author dada
*
* @param <E>
*/
class Node<E> {
E item;
Node<E> next;
//构造函数
Node(E element) {
this.item = element;
this.next = null;
}
}
class Students {
private int id;
private String name;
public Students(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return " "+"Students [id=" + id + ", name=" + name + "]";
}
}