顺序存储虽然是一种很有用途的存储结构,但也有很多局限性:
(1)若要为线性表扩充存储空间,则需重新创建一个地址连续的更大的存储空间,并把原有的数据元素都复制到新的存储空间中;
(2)因为顺序存储要求逻辑上相邻的数据元素,在物理存储位置上也是相邻,这就使得增删的数据元素会引起平均约一半的数据元素的移动。
针对这些情况,我们通常采用链式存储结构。
链式存储结构不要求逻辑上相邻的数据元素在物理上也是相邻的,它是一组地址任意的存储单元来存放数据元素的值。
一、单链表
链表中每个结点包含存放数据元素值的数据域和存放指向逻辑相邻结点的指针域。若结点中只包含一个指针域,则称链表为单链表(Single Linked List)
1、结点类的描述
data | next |
结点类的结构图
package com.slowly.xxb;
public class Node {
private Object data ;
private Node next ;
public Node(){
this (null , null);
}
public Node(Object data , Node next) {
this .data = data;
this .next = next;
}
public Object getData(){
return data ;
}
public Node getNext(){
return next ;
}
public void setData(Object data){
this .data = data;
}
public void setNext(Node next){
this .next = next;
}
}
2、单链表类的描述
本类实现了IList接口,关于此接口可查看我的另一篇博文http://blog.youkuaiyun.com/hanxueyu666/article/details/51753433
由于单链表只需一个头指针就能唯一识别它,所以单链表的成员变量只需设置一个头指针即可。
package com.slowly.xxb;
import java.util.Scanner;
public class LinkList implements IList {
private Node head ;//单链表的头指针
public LinkList(){
head = new Node();
}
public LinkList( int n, boolean Order )throws Exception{
this ();//初始化头结点
if (Order )
create1( n);
else
create2( n);
}
//用尾插法顺序建立单链表,其中n为单链表的结点个数
private void create1( int n) throws Exception {
Scanner sc = new Scanner(System. in);
for (int j = 0; j< n; j++){
insert(length(), sc.next());
}
}
//用头插法法顺序建立单链表,其中n为单链表的结点个数
private void create2( int n) throws Exception {
Scanner sc = new Scanner(System. in);
for (int j = 0; j< n; j++){
insert(0, sc.next());
}
}
public void clear() {
head .setData( null);
head .setNext( null);
}
public boolean isEmpty() {
return head .getNext()== null;
}
public int length() {
Node p= head .getNext();
int len = 0;
while (p != null){
p= p.getNext();
++ len ;
}
return len ;
}
public Object get( int i) throws Exception {
Node p = head .getNext();
int j =0;
for (j =0; j< i-1; j++){
p= p.getNext();
}
if (j > i|| p== null){
throw new Exception( "第"+ i+ "个元素不存在" );
}
return p .getData();
}
//带头结点的单链表的插入操作
public void insert( int i, Object x) throws Exception {
Node p = head ;
int j = -1;
while (p != null&& j< i-1){
p= p.getNext();
++ j;
}
if (j > i-1|| p== null)
throw new Exception( "插入位置不合法" );
Node s = new Node(x );
s.setNext( p.getNext()); //注:一下两句,顺序不能颠倒!
p.setNext( s);
}
public void remove( int i) throws Exception {
Node p = head ;
int j = -1;
while (p != null&& j< i-1){
p= p.getNext();
++ j;
}
if (j > i-1|| p== null)
throw new Exception( "删除位置不合法" );
p.setNext( p.getNext().getNext());
}
public int indexof(Object x) {
Node p = head .getNext();
int j = 0;
while (p != null&& p.getData().equals( x)){
p = p .getNext();
++ j;
}
if (p != null)
return j ;
else
return -1;
}
public void display() {
Node p = head .getNext();
while (p != null){
System. out .println(p .getData());
p= p.getNext();
}
}
}
测试例子
package com.slowly.xxb;
public class exampledlb {
public static void main(String[] args) throws Exception {
LinkList L = new LinkList();
L.insert(0, 'a' );
L.insert(0, '1' );//此时a成为第一个元素,1成为第0个元素
L.insert(0, 'c' );//此时c为第0个元素,1为第一个元素,a为第二个元素
L.insert(3, 'd' );
L.insert(4, 'e' );
L.insert(5, 'f' );
Object data = L .get(1);
System. out .println(data );//1
}
}