定义:
1、为链式结构,开辟的是不连续的空间,故不支持索引。
2、每一个节点都包含着自身存储的数据与指向下一个节点的地址(尾节点存储的地址值为null)。只要得到头结点的指针(头结点的地址),就可以得到所有的数据。
分类:
- 单向链表:
public class Link<Type> {
private int size; //个数
private LinkNode<Type> node;//此为头指针
public Link() {
size=-1;
node=null;
}
public Link(Type data) {
size++;
node=new LinkNode<Type>(data,null);
}
public boolean isEmpty() {
return node==null;
}
public void insert(int index,Type data) {
if(index<0||index>size+1) {
throw new ArrayIndexOutOfBoundsException("插入异常");
}else {
if(this.node==null) {
this.node=new LinkNode<Type>(data,node);
}else {
LinkNode<Type> node=this.node;
if(index==0) {
this.node=new LinkNode<Type>(data,node); //必须加this指针,否则在最后得将node重新赋值
}
for(int i=0;i<index-1;i++) { //找到前一个位置的元素
node=node.link;
}
node.link=new LinkNode<Type>(data,node.link); //因为头结点的地址未发生变化,所以不需要使用this关键字
}
size++;
}
}
public void remove(int index) {
System.out.println(size);
if(node==null|| index<0||index>size+1) {
throw new ArrayIndexOutOfBoundsException();
}else {
LinkNode<Type> node=this.node;
if(index==0) {
this.node=this.node.link;
System.out.println("一运行"+node.data);
}else {
for(int i=0;i<index-1;i++) { //找到其前一个元素
node=node.link;
}
node.link=node.link.link;
}
size--;
}
}
public boolean find(Type data) {
LinkNode<Type> node=this.node;
if(data==null) {
while(node!=null ) {
if(node.data==null) {
return true;
}
node=node.link;
}
}else {
while(node!=null) {
if(data.equals(node.data)) {
return true;
}
node=node.link;
}
}
return false;
}
public Type get(int index) {
if(index<0 ||index>=size+1) {
throw new NullPointerException("索引错误");
}else {
LinkNode<Type> node=this.node;
for( int i=0;i<=index-1;i++) {
node=node.link;
}
return node.data;
}
}
public void print() {
LinkNode<Type> node=this.node;
while(node!=null) {
System.out.print(node.data+" ");
node=node.link;
}
System.out.println();
}
}
class LinkNode<Type>{
public Type data;
public LinkNode<Type> link;
public LinkNode() {
data=null;
link=null;
}
public LinkNode(Type data) {
this.data=data;
this.link=null;
}
public LinkNode(Type data,LinkNode<Type> link) {
this.data=data;
this.link=link;
}
}
- 循环链表
头结点不存储数据,当头结点中的地址存储的地址是头结点本身的地址时,此循环链表为空。
实现:
public class CLink<Type> {
private CLinkNode<Type> link; //此为头结点
public CLink() {
link=new CLinkNode<Type>();
link.node=link;
}
public CLink(Type data) {
link=new CLinkNode<Type>(data);
}
public void insert(int index,Type data) {
if(index<0 ) {
throw new NullPointerException("索引越界");
}else {
if(isEmpty()) {
link.node=new CLinkNode<Type>(data);
link.node.node=link;
}else {
if(index==0) {
link.node=new CLinkNode<Type>(data,link.node);
}else {
CLinkNode<Type> node=link;
for( int j=0;j<index-1;j++) {
node=node.node;
}
node.node=new CLinkNode<Type> (data,node.node);
}
}
}
}
public boolean find(Type data) {
CLinkNode<Type> link=this.link;
if(data==null) {
while(link.node!=this.link) {
if(link.data==null) {
return true;
}
link=link.node;
}
}else {
while(link.node!=this.link) {
if(data.equals(link.data)) {
return true;
}
link=link.node;
}
}
return false;
}
public boolean isEmpty() {
return link==link.node;
}
public void print() {
CLinkNode<Type> link=this.link.node;
while(link.node!=this.link) {
System.out.print(link.data+" ");
link=link.node;
}
System.out.println();
}
}
class CLinkNode<Type>{
public Type data;
public CLinkNode<Type> node;
public CLinkNode() {
data=null;
this.node=null;
}
public CLinkNode(Type data) {
this.data=data;
}
public CLinkNode(Type data,CLinkNode<Type> node) {
this.data=data;
this.node=node;
}
}
- 双向链表
同样的,头结点不存储数据。只存储其做链接与右链接。当其左链接与右链接都为连接本身的时候的时候,为空。
实现:
public class DLink<Type>{
private DLinkNode<Type> node;//头指针
private DLinkNode<Type> current;
public DLink() {
node=new DLinkNode<Type>();
node.llink=node.rlink=node;
current=null;
}
public void insert(Type data) {
if(isEmpty()) {
current=node.rlink=new DLinkNode<Type>(data,node,node.rlink);
current.rlink.llink=current;
}
else {
current.rlink=new DLinkNode<Type>(data,current,current.rlink);
current.rlink.llink=current;
}
}
public void remove() {
if(current==null) {
throw new NullPointerException("当前元素为空");
}else {
current.rlink.llink=current.llink;
current.llink.rlink=current.rlink;
current=current.rlink;
if(current==node) {
current=null;
}
}
}
public boolean find(Type data) {
DLinkNode<Type> node=this.node;
if(data==null) {
while(node.rlink!=this.node) {
if(node.data==null) {
return true;
}
node=node.rlink;
}
}else {
while(node.rlink!=this.node) {
if(data.equals(node.data)) {
return true;
}
node=node.rlink;
}
}
return false;
}
public boolean isEmpty() {
return node.rlink==node;
}
public int size() {
int size=0;
DLinkNode<Type> node=this.node;
while(node.rlink!=this.node) {
size++;
node=node.rlink;
}
return size;
}
public void print() {
DLinkNode<Type> node=this.node.rlink;
while(node!=this.node) {
System.out.print(node.data+" ");
node=node.rlink;
}
System.out.println();
}
}
class DLinkNode<Type>{
public Type data;
public DLinkNode<Type> llink;
public DLinkNode<Type> rlink;
public DLinkNode() {
data=null;
llink=rlink=null;
}
public DLinkNode(Type data) {
this.data=data;
this.llink=this.rlink=null;
}
public DLinkNode(Type data,DLinkNode<Type> llink,DLinkNode<Type> rlink) {
this.data=data;
this.llink=llink;
this.rlink=rlink;
}
}
总的来说,链式结构存储的空间可以不连续,故可以动态的扩展内存空间,但是相应的,不能通过索引来直接获取某值。
若有不足,请多多指教