顺序表与单线表(java实现)
- 线性表:有多个数据特性相同的元素构成的有限序列
- 线性表基本操作
- 创造并初始化线性表
- 返回当前线性表数据元素个数
- 插入数据元素
- 删除数据元素
- 查询数据元素
- 顺序表实现
- 单链表实现
顺序表实现
-
顺序表实现原理其实就是定义一个数组用来存放数据元素,在定义数组时先给定数组为非常大的空间,通过顺序表的相关操作存取数据,同时用一个计数变量size来记录数组已经存放了多少个数据元素
-
顺序表的基本结构
public class List
{
//顺序表可存放数据个数最大值
private int MaxSise;
//数据存放数组
private Object[] list;
//顺序表数据元素个数
private int size;
/**************以下代码为顺序表相关操作*********************/
}
- 顺序表初始化
public List()
{
MaxSize = 100;
list = new Object[MaxSize];
size = 0;
}
- 返回顺序表长度
public int length()
{
return size;
}
- 顺序表插入
public boolean add(int index,Object element)
{
//索引错误
if(index < 0 && index >= MaxSize || size >= MaxSize)
return false;
else
{
//从后向前依次后移数据
for(var j = size;j > index;j--)
list[j] = list[j-1];
list[index] = element;
size++;
return true;
}
}
- 顺序表删除
public Object remove(int index)
{
//索引错误
if(index < 0 && index >= MaxSize || size < 0)
return null;
else
{
//从前向后依次前移数据
for(var j = index+1;j < size;j++)
list[j-1] = list[j];
size--;
return list[index];
}
}
- 查询数据元素
public Object get(int index)
{
//索引错误
if(index < 0 && index >= MaxSize)
return null;
else
{
return list[index];
}
}
顺序表总结
- 优点: 无需为表示表中元素之间的逻辑关系而增加额外的存储空间,并且可以快速地存取表中任意位置的元素
- 缺点:插入和删除操作需要移动大量元素;当线性表长度变化较大时,难以确定存储空间
单链表的实现
1. 单链表实现原理:单链表有多个相同类型结点构成,每个结点有两个区域,第一个区域存放数据元素,第二个区域存放下一结点引用,单链表的各个结点之间的物理地址并不连续,各个结点是通过存储下一结点引用来达到<形成逻辑关系2. 结点类
//元素结点类
class Node
{
//存放数据
private Object data;
//下一数据元素引用
private Node next;
public Node(Object data)
{
this.data = data;
next = null;
}
//data的get,set方法
public void setData(Object data)
{
this.data = data;
}
public Object getData()
{
return data;
}
//next的get,set方法
public void setNext(Node data)
{
this.next = next;
}
public Node getNext()
{
return next;
}
}
- 单链表基本结构
public class List
{
//单链表头引用
private Object head;
//单链表尾引用
private Object rail;
//单链表长度
private int length;
/*
........
以下为单链表操作
........
*/
}
- 创建并初始化单链表
public List()
{
//创造一个元素结点实例作为头结点
head = new Node();
rail = head;
length = 0;
}
- 插入数据元素
//将元素element插入到List最前
public void addHead(Object element)
{
var q = new Node(element);
q.setNext(head);
head = q;
//链表表为空时,插入结点改变tail
if(tail == head)
{
tail = q;
}
length++;
}
//将元素element插入到List最后
public void addTail(Object element)
{
var q = new Node(element);
q.setNext(tail.getNext());
tail.setNext(q);
tail = q;
length++;
}
//将元素element插入到indexz处
private boolean add(int index,Object element)
{
//索引错误
if(index < 0 || index > length)
{
return false;
}
//在List前插入
else if(index == 0)
{
addHead(element);
}
//在List尾插入
else if(index == length)
{
addTail(element);
}
else
{
Node p = head;
var j = -1;
//使p引用第index-1个结点
while(p.getNext() && j<index-1)
{
p = p.getNext();
j++;
}
var q = new Node(element);
q.setNext(p.getNext());
p.setNext(q);
length++;
}
return true;
}
- 数据元素删除
//删除List第index个结点
public Object remove(int index)
{
//索引错误
if(index < 0 || index > length || length == 0)
{
return null;
}
else
{
Node q = null;
//删除List第一个结点
if(index == 0)
{
q = head.getNext();
head.setNext() = q.getNext();
}
//删除List最后一个结点
else if(index == length)
{
q = tail;
tail.setNext() = q.getNext();
}
//删除结点在0~length结点之间
else
{
Node p = head;
var j = -1;
//使p引用第index个结点
while(p.getNext() && j < index-1)
{
p = p.getNext();
j++;
}
q = p.getNext();
p.setNext(q.getNext());
}
length--;
return q;
}
}
注意:因为单链表各结点物理地址不是连续的,并不像数组那样方便查询数据元素,就要特别注意循环终止条件
7. 返回单链表长度
//返回链表长度
public int getLength()
{
return length;
}
- 查询数据元素
//返回List中index索引处的结点
public Object get(int index)
{
//索引错误
if(index < 0 || index >= length)
{
return null;
}
else
{
var j = 0;
Node p = head.getNext();
while(j < index)
{
p = p.getNext();
j++;
}
return p;
}
}
- 添加其他操作
//返回对象o在List的索引
//对象o在List中返回索引,否则返回-1
public int getIndex(Object o)
{
var index = -1;
Node p = head;
while (p && p.equals(o))
{
P = p.getNext();
index++;
}
if(index < 0 || index >= length)
{
return -1;
}
else
{
return index;
}
}
单链表总结:
- 优点:单链表不需要分配存储空间,只要有就可以分配,元素个数也不受限制
- 缺点:单链表查询数据元素不方便