数据结构 JAVA描述(一) 线性表

一、线性表的抽象数据类型描述

IList

package List;

public interface IList {

    public void clear();

    public boolean isEmpty();

    public int length();

    public Object get(int i) throws Exception;

    /**
     * @description 在线性表的第i个元素之前插入一个值为x的数据元素 
     * @param i  0<=i<=length()
     * @param x
     * @throws Exception
     * @time 2015年12月22日 下午9:21:24
     */
    public void insert(int i, Object x) throws Exception;

    public void remove(int i) throws Exception;

    public int indexOf(Object x);

    public void display();
}

二、线性表的顺序存储

顺序表的特点

  • 在线性表中逻辑上相邻的数据元素,在物理存储位置上也是相邻的。
  • 存储密度高,但要预先分配,可能会造成空间的浪费。
  • 便于随机存取
  • 不便于插入和删除操作,会引起大量的数据元素的移动

顺序表类的描述

SqList

package List;

public class SqList implements IList {

    private Object[] listElem;  // 线性表存储空间
    private int curLen; // 线性表的当前长度


    /**
     * @description 构造一个存储空间容量为maxSize的线性表
     * @param maxSize
     * @time 2015年12月22日 下午9:50:05
     */ 
    public SqList(int maxSize) {
        curLen = 0;
        listElem = new Object[maxSize];
    }

    public void clear() {
        curLen = 0;
    }

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

    public int length() {
        return curLen;
    }


    /**
     * @description 读取线性表的第i个元素并返回其值
     * @param i 0<=i<=length()
     * @return
     * @throws Exception
     * @time 2015年12月22日 下午9:50:21
     */
    public Object get(int i) throws Exception {
        if (i < 0 || i > curLen - 1)
            throw new Exception("第" + i + "个元素不存在.");
        return listElem[i];
    }

    /**
     * @description 在线性表的第i个元素之前插入一个值为x的数据元素
     * @param i
     * @param x
     * @throws Exception
     * @time 2015年12月22日 下午9:50:34
     */
    public void insert(int i, Object 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++;   
    }

    public void remove(int i) throws Exception {
        if (i < 0 || i > curLen - 1)
            throw new Exception("删除位置不合法");
        for (int j = i; j < curLen - 1; j++)
            listElem[j] = listElem[j + 1];
        curLen--;
    }

    /**
     * @description 返回线性表中首次出现指定的数据元素的位序号;若线性表中不包含此数据元素,则返回-1 
     * @param x
     * @return
     * @time 2015年12月22日 下午9:51:06
     */
    public int indexOf(Object x) {
        int j = 0;
        while (j < curLen && !listElem[j].equals(x))
            j++;
        if (j < curLen)
            return j;
        else
            return -1;
    }

    public void display() {
        for (int j = 0; j < curLen; j++)
            System.out.println(listElem[j] + " ");
        System.out.println();
    }

}

三、线性表的链式存储

Node

//结点类的描述
class Node {
    private Object data;
    private Node next;

    public Node() {
        this(null, null);
    }

    public Node(Object data) {
        this(data, null);
    }

    public Node(Object data, Node next) {
        this.data = data;
        this.next = next;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }
}

LinkList

// 带头结点的单向链表
public class LinkList implements IList {
    private Node head;

    public LinkList() {
        head = new Node();
    }

    public LinkList(int n, boolean Order) throws Exception {
        this();
        if (Order)
            //用尾插法顺序建立单链表
            create1(n);
        else
            //用头插法顺序创建单链表
            create2(n);
    }


    public Node getHead() {
        return head;
    }

    public void setHead(Node head) {
        this.head = head;
    }

    // 尾插法顺序建立单链表
    private void create2(int n) throws Exception {
        Scanner sc = new Scanner(System.in);
        for (int j = 0; j < n; j++) {
            insert(length(), sc.next());
        } 
    }

    // 头插法逆序建立单链表
    private void create1(int n) throws Exception {
        Scanner sc = new Scanner(System.in);
        for (int j = 0; j < n; j++) {
            insert(0, sc.next());
        }
    }

    public void clear() { 
        head.setNext(null);
    }

    public boolean isEmpty() {
        return head.getNext() == null;
    }

    public int length() {
        Node p = head.getNext();
        int length = 0;
        while (p != null) {
            p = p.getNext();
            ++length;
        }
        return length;
    }

    public Object get(int i) throws Exception {
        // p指向首结点
        Node p = head.getNext();
        // j为计数器
        int j = 0;
        while (p != null && j < i) {
            p = p.getNext();
            ++j;
        }
        // p=null就代表i已经超过length()-1了
        if (i < 0 || p == null) {
            throw new Exception("第" + i + "个元素不存在");
        }
        return p.getData();
    }

    /**
     * @description 带头结点的单链表上的插入 
     * @param i
     * @param x
     * @throws Exception
     * @time 2015年12月22日 下午10:15:16
     */
    public void insert(int i, Object x) throws Exception {
        Node p = head;
        int j = -1;
        // 寻找第i个位置的前驱(即第i-1个位置)
        while (p != null && j < i - 1) {
            p = p.getNext();
            ++j;
        }
        //j!=i-1是判断i是负数,等同于i<0;p==null是判断i的位置超过了最大长度(length())
        if (j != i - 1 || p == null)
            throw new Exception("插入位置不合法");

        Node s = new Node(x);
        s.setNext(p.getNext());
        p.setNext(s);
    }

    public void remove(int i) throws Exception {
        Node p = head;
        int j = -1;
        // 寻找第i个位置的前驱  p.getNext() != null为判断i必须
        while (p.getNext() != null && j < i - 1) {
            p = p.getNext();
            ++j;
        }
        if (j != i - 1 || p.getNext() == null)
            throw new Exception("删除位置不合法");

        p.setNext(p.getNext().getNext());

    }

    /**
     * @description 按值查找首次出现的位置,没有找到则返回-1 
     * @param x
     * @return
     * @time 2015年12月22日 下午10:13:46
     */
    public int indexOf(Object x) {
        // p指向首结点,j是计数器
        Node p = head.getNext();
        int j = 0;
        while (p != null && !p.getData().equals(x)) {
            p = p.getNext();
            ++j;
        }
        //若找到了该值,则p指向某一结点,不会为null
        if (p != null)
            return j;
        else
            return -1;
    }

    public void display() {
        Node node = head.getNext();
        while (node != null) {
            System.out.print(node.getData() + " ");
            node = node.getNext();
        }
        System.out.println();
    }

    /**
     * @description 删除单链表中重复的结点 从单链表首结点开始依次将单链表中每个结点与它后面的所有结点进行比较
     * @throws Exception
     * @time 2015年12月22日 下午10:31:51
     */
    public void removeRepeatElem() throws Exception {
        // p指向首结点 (区别于头结点)
        Node p = head.getNext(), q;
        while (p != null) {
            int order = indexOf(p.getData());
            q = p.getNext();
            while (q != null) {
                if (p.getData().equals(q.getData()))
                    // 调用前面写好了的的删除方法
                    remove(order + 1);
                else
                    ++order;
                q = q.getNext();
            }
            p = p.getNext();
        }
    }

    /**
     * @description 将两个有序单链表la和lb合并成一个新的有序单链表,借助3个指针pa,pb,pc,pa指向la首结点,pb指向lb首结点,pc指向la头结点
     *              当pa.getData() @param la
     * @param lb
     * @return
     * @time 2015年12月22日 下午10:38:09
     */
    public LinkList mergeList(LinkList la, LinkList lb) {
        Node pa = la.getHead().getNext();
        Node pb = lb.getHead().getNext();
        Node pc = la.getHead();
        int da, db;
        while (pa != null && pb != null) {
            da = Integer.valueOf(pa.getData().toString());
            db = Integer.valueOf(pb.getData().toString());           
            if (da <= db) {
                pc.setNext(pa);
                pc = pa;
                pa = pa.getNext();
            } 
            //
            else {
                pc.setNext(pb);
                pc = pb;
                pb = pb.getNext();
            }
        }
        pc.setNext(pa != null ? pa : pb);
        return la;
    }

}

四、双向循环链表

DuLNode

package List;

import java.util.Scanner;

class DuLNode {
    private Object data;
    private DuLNode prior;
    private DuLNode next;

    public DuLNode() {
        this(null);
    }

    public DuLNode(Object data) {
        this.data = data;
        this.prior = null;
        this.next = null;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public DuLNode getPrior() {
        return prior;
    }

    public void setPrior(DuLNode prior) {
        this.prior = prior;
    }

    public DuLNode getNext() {
        return next;
    }

    public void setNext(DuLNode next) {
        this.next = next;
    }
}

DuLinkList

// 带头结点的双向循环链表
public class DuLinkList implements IList {
    private DuLNode head;

    public DuLinkList() {
        head = new DuLNode();
        head.setPrior(head);
        head.setNext(head);
    }

    // 头插法逆向创建双向循环链表
    public DuLinkList(int n) throws Exception {
        this();
        Scanner sc = new Scanner(System.in);
        for (int j = 0; j < n; j++) {
            insert(0, sc.next());
        }
    }

    public DuLNode getHead() {
        return head;
    }

    public void setHead(DuLNode head) {
        this.head = head;
    }

    public void clear() {
        head.setPrior(head);
        head.setNext(head);
    }

    public boolean isEmpty() {
        return head.getNext().equals(head);
    }

    public int length() {
        DuLNode p = head.getNext();
        int length = 0;
        while (!p.equals(head)) {
            p = p.getNext();
            ++length;
        }
        return length;
    }

    public Object get(int i) throws Exception {
        DuLNode p = head.getNext();
        int j = 0;
        while (!p.equals(head) && j < i) {
            p = p.getNext();
            ++j;
        }
        if (j > i || p.equals(head)) {
            throw new Exception("第" + i + "个元素不存在");
        }
        return p.getData();
    }

    /**
     * @description 注意这里:双向链表的增加找的是当前结点,而单向链表的增加找的是前驱
     * @param i
     * @param x
     * @throws Exception
     * @time 2015年12月22日 下午10:58:04
     */
    public void insert(int i, Object x) throws Exception {
        DuLNode p = head.getNext();
        int j = 0;
        while (!p.equals(head) && j < i) {
            p = p.getNext();
            ++j;
        }
        if (j != i)
            throw new Exception("插入位置不合法");
        DuLNode s = new DuLNode(x);
        p.getPrior().setNext(s);
        s.setPrior(p.getPrior());
        s.setNext(p);
        p.setPrior(s);

    }


    public void remove(int i) throws Exception {
        DuLNode p = head.getNext();
        int j = 0;
        while (!p.equals(head) && j < i) {
            p = p.getNext();
            ++j;
        }
        if (j != i || p.equals(head))
            throw new Exception("删除位置不合法");
        p.getPrior().setNext(p.getNext());
        p.getNext().setPrior(p.getPrior());
    }

    public int indexOf(Object x) {
        DuLNode p = head.getNext();
        int j = 0;
        while (!p.equals(head) && !p.getData().equals(x)) {
            p = p.getNext();
            ++j;
        }
        if (!p.equals(head))
            return j;
        else
            return -1;
    }

    public void display() {
        DuLNode node = head.getNext();
        while (!node.equals(head)) {
            System.out.print(node.getData() + " ");
            node = node.getNext();
        }
        System.out.println();
    }

}

你可能感兴趣的:(数据结构)