线性表

线性表是 n 个元素构成的有序序列。对线性表的存储方式通常有数组和链表两种方式。

不管哪种存储方式,线性表基本操作主要有:

  • insert(int v, int i ) : 在位序 i 前插入一个新元素 v
  • delete( int i ) : 删除指定位序 i 的元素
  • listLength() : 返回线性表 L 的长度 n
  • find( int v ) : 在线性表 L 中查找 v 的第一次出现位置
  • findKth( int K ) : 根据位置 K,返回相应元素

数组

如下主要演示以数组为存储方式的线性表的基本操作。

声明一个线性表的类型

array 主要负责帮助线性表以数组形式存储数据。

public class MyListArray {
    private int[] array;
    private int last;      //最后一个元素所在数组中的下标位置
}
find(查找)

遍历数组 array,查找值并返回值位置。

// 查找   
public int find(int v){
    int i = 0;
    while(i <= last && array[i]!=v)
        i++;
    if(i > last) return -1;   /*如果没有找到,返回 -1*/
    else return i;       /*找到后返回的是存储位置*/
}
insert(插入)

先看一张图:

 /**
     * 插入
     * @param v 要插入的值
     * @param i 要插入的位置
     */
    public void insert(int v, int i){
        int j;
        if(last == array.length-1){  /*表空间已满,不能插入*/
            System.out.println("表满");
            return;
        }

        if(i<1 || i>last+2){   
            System.out.println("位置不合法");
            return;
        }

        for(j = last; j>=i-1; j--)
            array[j+1] = array[j];  /*将 ai~an 倒序向后移动*/   
        array[i-1] = v;             /*新元素插入*/
        last++;                     /*last仍指向最后元素*/
        return;
    }
delete(删除)

先看一直图片:

/**
     * 删除
     * @param i 要删除的元素的位置
     */
    public void delete(int i){
        int j;
        if(i<1 || i>last+1){
            System.out.println("位置不合法");
            return;
        }
        for(j=i; j<=last; j++)
            array[j-1]=array[j];    /*将 ai+1~an 顺序向前移动*/    
        last--;                     /*last仍指向最后元素*/
        return;
    }

单链表

如下主要演示以单链表为存储方式的线性表的基本操作。

声明一个线性表的类型

单链表包含多个结点,每个结点有一个指向后继元素的 next 指针。最后一个结点的 next 指针为 null。

public class MyListNode {
    private int data;          /*当前对象结点所存的数据*/
    private MyListNode next;
    public MyListNode(int data){
        this.data = data;
    }
    public void setData(int data){
        this.data = data;
    }
    public int getData() {
        return data;
    }
    public void setNext(MyListNode next) {
        this.next = next;
    }
    public MyListNode getNext() {
        return next;
    }
}
listLength (线性表长度)

listLength() 函数输出链表长度,主要思路是遍历链表,当 next 指针输出为 null 时遍历结束,用 lenght 记录长度

int listLength(MyListNode headNode){
    int length = 0;
    MyListNode currentNode = headNode;     /*currentNode 指向第一个节点*/
    while(currentNode != null){
        length++;                          
        currentNode = currentNode.getNext();
    }
    return length;
}
find 和 findKth (查找)

遍历整个链表,返回查找到的结点。

/**
 * 按序号查找
 * @param position 序号
 * @param headNode 头节点
 * @return
 */
MyListNode findKth(int position, MyListNode headNode){
    MyListNode currentNode = headNode;
    int i = 1;
    while(currentNode!=null && i<position){
        currentNode = currentNode.getNext();
        i++;
    }
    if(i==position) return currentNode;
    else return null;
}

/**
 * 按值查找
 * @param v 所要查询的值
 * @param headNode 头节点
 * @return
 */
MyListNode find(int v, MyListNode headNode){
    MyListNode currentNode = headNode;
    while(currentNode != null && currentNode.data != v){
        currentNode = currentNode.getNext();
    }
    return currentNode;
}
insert (插入)

插入操作分为以下3种情况:

1)在链表的表头插入一个新结点

  • 更新新节点 next 指针,使其指向当前的表头节点
  • 更新表头指针的值,使其指向新节点。

2)在链表的表尾后插入一个新节点

  • 新结点的 next 指针指向 null
  • 最后一个结点的 next 指针指向新结点

3)在链表的中间插入一个新结点,如下操作可以完成

  • 如果要在位置3增加一个元素,则需要将指针定位于链表的位置2。假设第二个结点为位置结点,新结点的 next 指针指向位置结点的下一个结点
  • 位置结点的 next 指针指向新结点

MyListNode insert(int v, int position, MyListNode headNode){
    MyListNode nodeToInsert;
    if(position==1){                 /*表头插入*/
        nodeToInsert = new MyListNode(v);
        nodeToInsert.setNext(headNode);
        return nodeToInsert;
    }

    MyListNode pre = findKth(position-1, headNode);       /*查找第i-1个节点*/
    if(pre == null){
        System.out.println("参数position错误");
        return null;
    }else{                                 /*表中或者表尾插入*/
        nodeToInsert = new MyListNode(v);
        nodeToInsert.setNext(pre.getNext());
        pre.setNext(nodeToInsert);
        return headNode;
    }
}
delete (删除)

删除操作分为以下3种情况:

1)删除单向链表的第一个结点。

2)删除单向链表的最后一个结点。

3)删除单向链表的中间一个结点。

代码

MyListNode delete(int position, MyListNode headNode){
    if(position == 1){        /*若要删除的是表第一个节点*/
        MyListNode currentNode = headNode.getNext();
        headNode = null;
        return currentNode;
    }       

    MyListNode pre = findKth(position, headNode);   /*查找第i-1个节点*/

    if(pre == null){
        System.out.println("节点不存在");
        return null;
    }else if(pre.getNext() == null){
        System.out.println("节点不存在");
        return null;
    }else{       /*删除的是中间或者最后一个节点*/
        MyListNode currentNode = pre.getNext();
        pre.setNext(currentNode.getNext());
        currentNode = null;
        return headNode;
    }
}

results matching ""

    No results matching ""