线性表是最基本的一种数据结构,它是一种线性结构,是一种含有n>=0个结点的序列,其中开始结点没有前驱,终端结点没有后继,其他结点有且只有一个前驱和后继。
特征:集合中必然存在且只有一个开始结点和终端结点。其他结点均有一个前驱和后继
下面先实现线性表接口IList,其中定义了对该表的许多操作:
package ilist;
public interface IList<E>
{
public void clear();//清空
public boolean isEmpty();//判空
public int length();//求表长
public E get(int i)throws Exception;//取出某一个元素
public int indexOf(E x)throws Exception;//某一元素出现的第一个位置
public void insert(int i,E x)throws Exception;//在位置i插入一个新的元素
public void remove(int i)throws Exception;//删除位置号为i的数据元素
public void display();//打印表的数据元素
}
实现该线性表的接口有2种形式:
顺序表和链表,顺序表在逻辑结构是相邻、存储结构也是相邻的,一般用连续的存储单元来存储数据,属于静态表,其优点有便于随机存取
元素,但是在删除和插入数据时,需要移动大量的元素的位置。而链表是属于动态表,用不连续的存储单元来存储数据,优点是利于插入和删除,但是不方便访问数据。
下面是SqList的代码实现:
package SqList;
public class SqList<E> implements IList<E> {
protected E[] listElem;//存储数据
protected int curlen;
public SqList() {
curlen = 0;
listElem = null;
}
public SqList(int maxsize) {
curlen = 0;
listElem = (E[]) new Object[maxsize];
}
//清空操作
public void clear() {
curlen = 0;
}
public boolean isEmpty() {
return curlen == 0;
}
public int length() {
return curlen;
}
@Override
public E get(int i) throws Exception {
if (i < 0 || i > curlen - 1) {
throw new Exception("第" + i + "元素不存在");
}
return listElem[i];
}
@Override
public void insert(int i, E x) throws Exception {
if (curlen == listElem.length) {
throw new Exception("循序表已经满了");
}
if (i < 0 || i > curlen) {
throw new Exception("插入位置不合法");
}
for (int j = curlen; j > i; j--) {
listElem[j] = listElem[j - 1];
}
listElem[i] = x;
curlen++;
}
@Override
public void remove(int i) throws Exception {
if (this.isEmpty()) {
throw new Exception("循序表已经空了");
}
if (i < 0 || i >= curlen) {
throw new Exception("删除位置不合法");
}
for (int j = i; j < curlen - 1; j++) {
listElem[j] = listElem[j + 1];
}
curlen--;
}
public int indexOf(E x) {
int j = 0;
while (j < curlen && !listElem[j].equals(x)) {
j++;
}
if (j < curlen) {
return j;
} else {
return -1;
}
}
@Override
public void display() {
for (int j = 0; j < curlen; j++) {
System.out.println(listElem[j]);
}
}
}
链表的实现方法是,每一个结点由2部分组成:数据域和指针域,数据域用于存储数据元素,而指针域用来存储它下一个结点的引用值(Node);除此之外,链表需要一个头结点,其指针域指向头结点,而数据域为空,结点类描述如下:
public class Node<E> {
private E data;//存储数据元素
private Node next;//存储下一个结点的引用值
public Node() {
data = null;
next = null;
}
public Node(E data) {
this.data = data;
next = null;
}
public E getData() {
return data;
}
public void setData(E data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
链表代码实现如下:
import SqList.IList;
public class LinkList<E> implements IList<E> {
private Node<E> head;
private int curlen;
public LinkList() {
head = new Node<E>();
curlen = 0;
}
public Node<E> getHead() {
return head;
}
@Override
public void clear() {
head.setNext(null);
curlen = 0;
}
@Override
public boolean isEmpty() {
return head.getNext() == null;
}
@Override
public int length() {
return curlen;
}
@Override
public E get(int i) throws Exception {
if (i < 0 || i > curlen - 1) {
throw new Exception("");
}
Node<E> p = head.getNext();
int j = 0;
while (p != null && j < i) {
p = p.getNext();
++j;
}
return p.getData();
}
@Override
public void insert(int i, E x) throws Exception {
if (i < 0 || i > curlen) {
throw new Exception("dfghj");
}
Node<E> s = new Node<E>(x);
Node<E> p = head;
int j = -1;
while (p != null && j < i - 1) {
p = p.getNext();
++j;
}
s.setNext(p.getNext());
p.setNext(s);
curlen++;
}
@Override
public void remove(int i) throws Exception {
if (this.isEmpty()) {
throw new Exception("链表已空");
}
if (i < 0 || i > curlen - 1) {
throw new Exception("删除位置不合法");
}
Node<E> p = head;
int j = -1;
while (p.getNext() != null && j < i - 1) {
p = p.getNext();
++j;
}
p.setNext(p.getNext().getNext());
curlen--;
}
@Override
public int indexOf(E x) {
Node<E> 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;
}
}
@Override
public void display() {
Node<E> node = head.getNext();
while (node != null) {
System.out.println(node.getData());
node = node.getNext(); // 取下一个结点
}
}
}