数据结构实现分享(1)

1.数组实现可以扩容的顺序表

  1 /**
  2  * 利用数组实现可以自动扩容的顺序表,顺序表下标从1开始
  3  * 对于线性表来说,插入的新的数据不能使表的中间出现空隙,所以插入位置在1-length之间
  4  * @author ZW
  5  * @param <T>
  6  * @version 1.1
  7  */
  8 public class list<T> {
  9 
 10     final int inisize = 10;// 线性表的初始大小
 11 
 12     private int length;// 线性表的实时长度
 13 
 14     private T[] listArray;// 利用泛型数组来实现线性表
 15 
 16     /**
 17      * 线性表具有的方法:初始化,新增元素,删除元素,查找元素,获取元素,修改元素等。
 18      */
 19     public list() {
 20         this.length = 0;
 21         listArray = (T[]) new Object[inisize];
 22     }
 23 
 24     public list(int n) {
 25         if (n < 0) {
 26             System.out.println("error");
 27             System.exit(1);
 28         } else {
 29             this.length = 0;
 30             listArray = (T[]) new Object[n];
 31         }
 32     }
 33 
 34     public boolean add(T obj, int pos) {
 35         // 如果插入的位置不合法
 36         if (pos < 1 || pos > length + 1) {
 37             System.out.println("pso值不合法");
 38             return false;
 39         }
 40         // list容量不足,对数组扩容
 41         if (length == listArray.length) {
 42             T[] p = (T[]) new Object[length * 2];// 扩容
 43             for (int i = 0; i < length; i++) {
 44                 p[i] = listArray[i];
 45             }
 46             listArray = p;
 47         }
 48         for (int i = length; i >= pos; i--) {
 49             listArray[i] = listArray[i - 1];
 50         }
 51         listArray[pos - 1] = obj;
 52         length++;
 53         return true;
 54     }
 55 
 56     public Object delete(int pos) {
 57         if (isEmpty()) {
 58             System.out.println("error,顺序表为空");
 59             return null;
 60         } else if (pos < 1 || pos > length) {
 61             System.out.println("error,pos值不合法");
 62             return null;
 63         }
 64         T x = listArray[pos - 1];
 65         for (int i = pos; i <= length; i++) {
 66             listArray[i - 1] = listArray[i];
 67         }
 68         length--;
 69         return x;
 70     }
 71 
 72     public int find(Object obj) {
 73         if (isEmpty()) {
 74             System.out.println("error,线性表为空");
 75             return -1;
 76         } else {
 77             for (int i = 0; i < length; i++) {
 78                 if (obj.equals(listArray[i])) {
 79                     return i + 1;
 80                 }
 81             }
 82             return -1;
 83         }
 84     }
 85 
 86     public Object get(int pos) {
 87         if (isEmpty()) {
 88             System.out.println("error,线性表为空");
 89             return null;
 90         } else if (pos < 1 || pos > length) {
 91             System.out.println("error,pos值错误");
 92             return null;
 93         }
 94         return listArray[pos - 1];
 95     }
 96 
 97     public boolean modify(T obj, int pos) {
 98         if (isEmpty()) {
 99             System.out.println("error,线性表为空");
100             return false;
101         } else if (pos < 1 || pos > length) {
102             System.out.println("error,pos值错误");
103             return false;
104         }
105         listArray[pos - 1] = obj;
106         return true;
107     }
108 
109     public boolean isEmpty() {
110         return length == 0;
111     }
112 
113     public int size() {
114         // TODO 自动生成的方法存根
115         return length;
116     }
117 
118     public void nextOrder() {
119         for (int i = 0; i < length; i++) {
120             System.out.println(listArray[i]);
121         }
122 
123     }
124 
125     public void clear() {
126         length = 0;
127 
128     }
129 
130 }

 

2.链表实现顺序表

/*关于链表的注意事项:链表的位置从头元素的下一元素开始为1,但是链表的位置不代表链表中节点的实际地址(引用)
 * 因此,无论增删改都需要从第一个节点开始对链表进行依次查找,找到需要操作的节点地址(引用)*/
public class linkList<T> {

    private Node<T> head;// 头结点
    private int length;// 链表长度

    /* 单链表的无参构造 */
    public linkList() {
        this.length = 0;
        this.head = new Node<T>(null);
        // 该处不采用this.head=null; 其原因:链表创建时头结点是存在的,只不过其指向下个节点的引用为null。
    }

    /* 获取头结点地址 */
    public Node<T> getHead() {
        return this.head;
    }

    /* 向链表中插入一个元素 */
    public boolean insert(T obj, int pos) {
        if (pos < 1 || pos > length + 1) {
            // 单链表并非通过数组实现,其长度受限于其上一个节点是否存在,故其插入位置不因>length+1
            System.out.println("pos值不合法");
            return false;
        }
        int num = 1;
        Node<T> p = head;
        Node<T> q = head.next;
        /*
         * 算法总结: 1.利用p q来表示两个相邻链表,while遍历到要插入的位置。
         * 2.将前一节点P的next引用到要插入的元素,利用插入节点的构造方法将next引用到Q节点
         */
        while (num < pos) {
            p = q;
            q = q.next;
            num++;
        }
        p.next = new Node<T>(q, obj);
        length++;
        return true;
    }

    /* 删除链表中的一个元素 */
    public T remove(int pos) {
        if (empty()) {
            System.out.println("链表为空,无法删除!");
            return null;
        } else if (pos < 1 || pos > length + 1) {
            System.out.println("pos值不合法");
            return null;
        } else {
            int num = 1;
            Node<T> p = head;
            Node<T> q = head.next;
            while (num < pos) {
                p = q;
                q = q.next;
                num++;
            }
            p.next = q.next;
            length--;
            return q.data;
        }

    }

    /* 获取链表中的一个元素 */
    public T get(int pos) {
        if (empty()) {
            System.out.println("链表为空,无法找到元素!");
            return null;
        } else if (pos < 1 || pos > length + 1) {
            System.out.println("pos值不合法");
            return null;
        } else {
            int num = 1;
            Node<T> p = head;
            Node<T> q = head.next;
            while (num < pos) {
                p = q;
                q = q.next;
                num++;
            }
            return q.data;
        }

    }

    /* 在链表中查找某个元素 */
    public int find(T obj) {
        if (empty()) {
            System.out.println("链表为空");
            return -1;
        } else {
            Node<T> q = head;
            for (int i = 1; i <= length; i++) {
                q = q.next;
                if (q.data.equals(obj)) {
                    return i;
                }
            }
            return -1;
        }

    }

    /* 在链表中更新某个元素 */
    public boolean modify(T obj, int pos) {
        if (empty()) {
            System.out.println("链表为空,无法更新元素!");
        } else if (pos < 1 || pos > length + 1) {
            System.out.println("链表为空,无法更新元素!");
            return false;
        }
        int num = 1;
        Node<T> q = head.next;
        while (num < pos) {
            q = q.next;
            num++;
        }
        q.data = obj;
        return true;
    }

    /* 判断链表是否为空 */
    public boolean empty() {
        return length == 0;
    }

    /* 求链表中的元素数 */
    public int size() {
        return length;
    }

    /* 遍历表中所有元素并向控制台输出 */
    public void printAll() {
        Node<T> p = head.next;
        while (p != null) {
            System.out.println(p.data);
            p = p.next;
        }
    }

    /* 销毁链表 */
    public void clear() {
        length = 0;
        head.next = null;
    }
}

链表节点的实现:

/**
 * 链表的节点类
 */
public class Node<T> {
    T data;// 节点的数据部分

    Node<T> next;// 节点的引用部分

    /* 节点的构造方法,参数为下个节点引用 */
    public Node(Node<T> n) {
        this.next = n;
    }

    /* 节点的构造方法,参数N初始化引用,参数data初始化数据 */
    public Node(Node<T> n, T data) {
        this.data = data;
        this.next = n;
    }

    /* 获取节点类数据的方法 */
    public T getdata() {
        return this.data;
    }

    /* 获取节点引用的方法 */
    public Node<T> getNext() {
        return this.next;
    }
}

 

posted @ 2019-09-03 10:25  hfSccc  阅读(168)  评论(0编辑  收藏  举报