分别实现3种类型的链表,这一篇用数组来实现线性表---
有序链表:链表元素或节点始终保持有序,链表元素为Comparable对象,主要体现在插入操作要插入在相应的序列位置
无序链表:无序,每次指定插入在哪(表头,尾,or指定元素之后)
索引链表:提供了许多与索引相关的操作
将三种实现的都有的公共操作定义在一个接口ADT中,对应于各自特征所特有的操作扩展在自己的类中,可以看到,其实就是插入操作(add)不同而已。
以上说明具体见下列ADT定义中的注释:
链表ADT:
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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,我们将实现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 ;
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;
}
{
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;
}
有序链表的实现:
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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 ++ ;
}
}
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操作不一样,其他完全相同,只贴出扩展部分不同的几个操作:
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
//
无序链表扩展的操作
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 ;
}
}
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,索引链表的数组实现
扩展的不同操作:
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
//
索引链表扩展的操作
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 ;
}
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 ;
}
数组实现的很多地方都在移动元素,在插入和删除上没有优势,它的优势在于随机存取。