用数组实现3种类型的线性表(有序链表、无序链表、索引链表)

来源:互联网 发布:getscript 获得js源码 编辑:程序博客网 时间:2024/06/06 13:19

分别实现3种类型的链表,这一篇用数组来实现线性表---

有序链表:链表元素或节点始终保持有序,链表元素为Comparable对象,主要体现在插入操作要插入在相应的序列位置

无序链表:无序,每次指定插入在哪(表头,尾,or指定元素之后)

索引链表:提供了许多与索引相关的操作

将三种实现的都有的公共操作定义在一个接口ADT中,对应于各自特征所特有的操作扩展在自己的类中,可以看到,其实就是插入操作(add)不同而已。


以上说明具体见下列ADT定义中的注释:

链表ADT:

复制代码
package List;


/*1,我们将实现3中类型的链表:有序链表的元素是可比较对象,在插入删除时始终维持链表有序;无序链表是无序的,
* 插入时指定插入位置(链表首,尾,或指定元素之后);索引链表可以根据索引来存取元素(例如返回某个元素的索引,
* 返回某个索引上的元素,在某个索引处删除或插入元素等等)。他们的区别就在于插入的操作不一样。
* 2,将有序链表,无序链表,索引链表的公共操作定义为接口,不同的操作在类中扩展
*/


public interface ListADT {//3种链表的公共操作

public int size();

public boolean isEmpty();

public Object first();

public Object last();

public Object removeFirst();

public Object removeLast();

public Object remove(Object element);

public boolean contains(Object element);

}
复制代码


1,有序链表的数组实现

成员定义:

private Object[] contents;
private int rear;//将链表的一端固定在0,rear表示下一个可用单元的下标(也表示长度)
private static int SIZE = 10;


构造方法和数组动态扩展:

复制代码
public ArrayOrderedList()
{
contents
= new Object[SIZE];
rear
= 0;
}

public void expand()
{
Object[] larger
= new Object[size()*2];
for(int index = 0;index < rear;index++)
larger[index]
= contents[index];
contents
= larger;
}
复制代码


有序链表的实现:

复制代码
package List;

public class ArrayOrderedList implements ListADT {//有序链表

private Object[] contents;
private int rear;//将链表的一端固定在0,rear表示下一个可用单元的下标(也表示长度)
private static int SIZE = 10;


public ArrayOrderedList()
{
contents
= new Object[SIZE];
rear
= 0;
}

public void expand()
{
Object[] larger
= new Object[size()*2];
for(int index = 0;index < rear;index++)
larger[index]
= contents[index];
contents
= larger;
}




//三种链表的接口公共操作(实现是一样的)

public int size() {
return rear;
}

public boolean isEmpty() {
return (size() == 0);
}

public boolean contains(Object element) {
for(int index = 0;index < rear;index++)
if(element.equals(contents[index]))
return true;
return false;
}

public Object first() {
return contents[0];
}


public Object last() {
return contents[rear - 1];
}


public Object removeFirst() {
if(size() == 0)
{
System.out.println(
"表现在为空!!!不能删除");
return null;
}
Object result
= contents[0];
for(int index = 0;index < rear - 1;index++)
contents[index]
= contents[index+1];
rear
--;
return result;
}

public Object removeLast() {
if(size() == 0)
{
System.out.println(
"表现在为空!!!不能删除");
return null;
}
Object result
= contents[rear-1];
contents[rear
-1] = null;//也可以不置空,下次覆盖
rear--;
return result;
}

public Object remove(Object element) {
if(size() == 0)
{
System.out.println(
"表现在为空!!!不能删除");
return null;
}

for(int index = 0;index < rear;index++)
if(contents[index].equals(element))
{
Object result
= contents[index];
for(int i = index;i < rear-1;i++)
{
contents[i]
= contents[i+1];
//rear--;错误
}
rear
--;
return result;
}

return null;
}



//有序链表扩展的操作

public void add(Comparable element){
if(rear == contents.length)
expand();
for(int index = 0;index < rear;index++)
if(element.compareTo(contents[index]) < 0)//找到插入位置
{
for(int i = rear;i > index;i--)
contents[i]
= contents[i-1];
contents[index]
= element;
rear
++;
return;
}
contents[rear]
= element;
rear
++;
}

}
复制代码




2,无序链表的数组实现

就是add操作不一样,其他完全相同,只贴出扩展部分不同的几个操作:

复制代码
//无序链表扩展的操作

public void addToFront(Object element){
if(rear == contents.length)
expand();
for(int index = rear;index > 0 ;index--)
contents[index]
= contents[index-1];
contents[
0] = element;
rear
++;
}


public void addToRear(Object element){
if(rear == contents.length)
expand();
contents[rear]
= element;
rear
++;
}


public void addAfter(Object after,Object element){
if(rear == contents.length)
expand();
for(int index = 0;index < rear;index++)
if(contents[index].equals(after))
{
for(int i = rear;i > index+1;i--)
contents[i]
= contents[i-1];
contents[index
+1] = element;
rear
++;
return;
}
}
复制代码




3,索引链表的数组实现

扩展的不同操作:

复制代码
//索引链表扩展的操作

public void add(Object element){//在表尾插入
if(rear == contents.length)
expand();
contents[rear]
= element;
rear
++;
}

public void add(int index,Object element){//在指定索引上插入,后面的元素要后移
if(rear == contents.length)
expand();
for(int i = rear;i > index;i--)
contents[i]
= contents[i-1];
contents[index]
= element;
rear
++;
}

public void set(int index,Object element){//设置某个索引上的元素(覆盖原来的,不需要移动元素)
if(index >= rear)
{
System.out.println(
"只能在表的范围内设置");
return;
}
contents[index]
= element;
}

public Object get(int index){//返回某个索引上的元素
return contents[index];
}

public int indexOf(Object element){//返回某个元素的索引
for(int i = 0;i < rear;i++)
if(element.equals(contents[i]))
{
int index = i;
return index;
}
return -1;
}

public Object remove(int index){//移除指定索引上的元素
for(int i = index;i < rear;i++)
{
Object result
= contents[index];
contents[index]
= contents[index+1];
rear
--;
return result;
}
return null;
}

复制代码


 数组实现的很多地方都在移动元素,在插入和删除上没有优势,它的优势在于随机存取。
0 0
原创粉丝点击