1.线性表的顺序存储结构,类似ArrayList

package collectionsFramework.linearlist;

import java.util.Arrays;

/**
* @Package collectionsFramework.linearlist * @ClassName: Singlylinkedlist * @Description: TODO(arrayList的增删改查) * @author andy * @date 2013-11-21 下午05:39:53 */
public class SinglyLinkedList<T>{
private Object[] elementData;
private int size;
private int capacity;
private int defaultCapacity = 10;
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; public SinglyLinkedList(){
capacity = defaultCapacity;
elementData = new Object[capacity];
} public int getSize() {
return size;
} public boolean isEmpty(){
return size == 0;
} //在线性顺序表的开始处添加一个元素。
public void add(T element){
insert(element , size);
}
//在指定位置处添加一个元素
private void insert(T element, int index) {
if(index < 0 || index > size){
throw new IndexOutOfBoundsException("数组下标越界!");
}
ensureCapacity(index+1);
System.arraycopy(elementData, index, elementData, index+1, size-index);
elementData[index] = element;
size++;
} private void ensureCapacity(int size) {
if(size > capacity){
//容量增大两倍,即为原来的3倍
capacity = capacity + capacity<<1;
//如果其值比最大值还大
capacity = capacity >Integer.MAX_VALUE ? hugeCapacity(size):capacity; elementData = Arrays.copyOf(elementData, capacity);
}
} //如果值比MAX_ARRAY_SIZE还大,那么其返回值就是Integer.MAX_VALUE,否则就是MAX_ARRAY_SIZE
private static int hugeCapacity(int minCapacity) {
return minCapacity > MAX_ARRAY_SIZE ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
} //删除顺序线性表中指定索引处的元素
public T remove(int index){
if(index < 0 || index > size-1){
throw new IndexOutOfBoundsException("所要删除元素的索引越界");
}
T oldData = (T)elementData[index];
System.arraycopy(elementData, index+1, elementData, index, size-(index+1));
elementData[size-1] = null;
size--;
return oldData;
} //获取顺序线性表中索引为i处的元素
public T get(int i) {
if (i < 0 || i > size - 1){
throw new IndexOutOfBoundsException("数组下标越界!");
}
return (T)elementData[i];
} public String toString()
{
if (size == 0)
{
return "[]";
}
else
{
StringBuilder sb = new StringBuilder("[");
for (int i = 0 ; i < size ; i++ )
{
sb.append(elementData[i].toString() + ", ");
}
int len = sb.length();
return sb.delete(len - 2 , len).append("]").toString();
}
} public static void main(String[] args) {
SinglyLinkedList<String> list = new SinglyLinkedList<String>();
System.out.println(list);
list.add("a");
System.out.println(list);
list.add("b");
System.out.println(list);
list.add("c");
System.out.println(list);
list.add("d");
System.out.println(list);
list.add("e");
System.out.println(list);
list.remove(2);
System.out.println("remove之后:" + list);
System.out.println(list.get(2));
}
}

2.线性表的链式实现,是一个双向链表,类似LinkedList

package collectionsFramework.linearlist;

/**
* @Package collectionsFramework.linkedlist
*
* @ClassName: DoublyLinkedList
*
* @Description: TODO(LinkedList的增删改查)
*
* @author andy
*
* @date 2013-11-21 下午05:40:31
*/
public class DoublyLinkedList<T> {
private class Node<T> {
private T data;
private Node<T> prev;
private Node<T> next; public Node() { } public Node(T data, Node<T> prev, Node<T> next) {
this.data = data;
this.prev = prev;
this.next = next;
}
} private Node<T> header;
private Node<T> tail;
private int size; public DoublyLinkedList() {
header = null;
tail = null;
} // 返回链表的长度
public int length() {
return size;
} public boolean empty() {
return size == 0;
} //在链表尾部添加新节点
public T add(T element) {
if (empty()) {
header = new Node<T>(element, null, null);
tail = header;
} else{
Node<T> newNode = new Node<T>(element , tail, null);
tail.next = newNode;
tail = newNode;
}
size++;
return element;
} //在链表头部添加新节点
public T addFirst(T element) {
header = new Node<T>(element, null, header);
if(empty()){
tail = header;
}
size++;
return element;
} public T addLast(T element) {
return add(element);
} //指定位置出插入元素
public T add(int index, T element) {
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException("线性表索引越界");
}
// 如果还是空链表
if (empty()) {
add(element);
} else {
if(index == 0){
addFirst(element);
}else{
//插入点的前一个结点
Node<T> prev = getNudeByIndex(index-1);
//a、b、c、d
//在c这是插入一个e结点,并且它的prev指向上面的b,它的next指向d,但是b的next引用和d的prev引用还是没有变
Node<T> newNode = new Node<T>(element, prev, prev.next);
//b的next引用指向e
prev.next = newNode;
//d的prev引用指向e
prev.next.prev = newNode;
size++;
}
} return element;
} //根据索引index获取指定位置的节点,二分法查找元素
public Node<T> getNudeByIndex(int index){
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException("线性表索引越界");
} if(empty()){
return null;
} if(index <= size/2){
int i=0;
for(Node<T> currentNode = header; i <= size/2 && currentNode!=null; i++,currentNode=currentNode.next){
if(i == index){
return currentNode;
}
}
}else{
int i=size-1;
for(Node<T> currentNode = tail; i > size/2 && currentNode!=null; i--,currentNode=currentNode.prev){
if(i == index){
return currentNode;
}
}
}
return null;
} //获取但不移除此列表的头(第一个元素)。
public T element() {
return getFirst();
} //获得指定索引出的数据
public T get(int index) {
if (index < 0 || index > size - 1) {
throw new IndexOutOfBoundsException("线性表索引越界");
} return getNudeByIndex(index).data;
} public T getFirst() {
return header == null? null:header.data;
} public T getLast() {
return tail == null? null:tail.data;
} public T offer(T element) {
return add(element);
} public T offerFirst(T element) {
return addFirst(element);
} public T offerLast(T element) {
return addLast(element);
} public T peek() {
return getFirst();
} public T peekFirst() {
return getFirst();
} public T peekLast() {
return getLast();
} public T poll() {
return removeFirst();
} public T pollFirst() {
return removeFirst();
} public T pollLast() {
return removeLast();
} public T pop() {
return removeFirst();
} public T push(T element) {
return addFirst(element);
} public T remove() {
return remove(0);
} public T remove(int index) {
if(index < 0 || index > size -1){
throw new IndexOutOfBoundsException("线性表索引越界");
} if(empty()){
return null;
}
Node<T> delNode;
if(index == 0){
//a、b、c、d、e 移除a结点,下面得到a结点
delNode = header;
//将b结点设置为头结点
header = delNode.next;
//并将b结点对上一个a节点的引用设置为空
delNode.next.prev = null;
//并将a结点对下一个b结点的引用设置为空
delNode.next = null;
//将删除结点设置为空
//delNode.data = null;
//delNode = null;
size--;
return delNode.data;
}else if(index == (size-1)){
//a、b、c、d、e 移除e结点,下面得到e结点
delNode = tail;
//得到d结点,并将d结点的下一点指向null
delNode.prev.next = null;
//并将e结点对上一个节点的引用设置为null
delNode.prev = null;
//将删除结点设置为空
//delNode.data = null;
//delNode = null;
size--;
return delNode.data; }else{
//a、b、c、d、e 移除c结点,下面得到c结点
delNode = getNudeByIndex(index);
//得到b结点,并将b结点的下一点指向d结点
delNode.prev.next = delNode.next;
//并将d结点对上一个节点的引用设置为b
delNode.next.prev = delNode.prev;
//并将c结点对b、d的引用设置为空
delNode.next = null;
delNode.prev = null;
size--;
return delNode.data;
}
} public T removeFirst() {
return remove(0);
} public T removeLast() {
return remove(size-1);
} public void clear() {
if(empty()){
return;
}
for (Node<T> node = header; node != null; node = node.next) {
node.data = null;
node.prev = null;
node.next = null;
}
header = null;
tail = null;
size = 0;
} public String toString()
{
//链表为空链表时
if (empty())
{
return "[]";
}
else
{
StringBuilder sb = new StringBuilder("[");
for (Node<T> current = header ; current != null
; current = current.next )
{
sb.append(current.data.toString() + ", ");
}
int len = sb.length();
return sb.delete(len - 2 , len).append("]").toString();
}
} public static void main(String[] args) {
DoublyLinkedList<String> linkedList = new DoublyLinkedList<String>();
System.out.println(linkedList);
linkedList.add("a");
linkedList.add("b");
linkedList.add("c");
linkedList.add("d");
System.out.println(linkedList);
System.out.println("移除对象:" + linkedList.removeFirst());
System.out.println(linkedList);
System.out.println("移除对象:" + linkedList.remove(2));
System.out.println(linkedList);
}
}

java_linear list的更多相关文章

随机推荐

  1. 理解NSAttributedString

    An NSAttributedString object manages character strings and associated sets of attributes (for exampl ...

  2. Errors

    Errors running builder 'Android Resource Manager' on project 'Demo'. java.lang.NullPointerException ...

  3. (spring-第5回【IoC基础篇】)spring容器从加载配置文件到实例化bean的内部工作机制

    前面讲过,spring的生命周期为:实例化前奏-->实例化-->实例化后期-->初始化前期-->初始化-->初始化后期-->bean的具体调用-->销毁前-- ...

  4. 几种判断asp.net中session过期方法的比较

    方法一:最麻烦也是最容易想到的方法,在每个页面的page_load()方法里面判断: protected void Page_Load(object sender, EventArgs e) { if ...

  5. 使用busybox构建根文件系统

    当我们在Qemu上运行起来自己编译的内核之后,需要使用busybox构建一个文件系统,将此文件系统挂载上去就可以使用busybox提供的各种命令了. 1.编译安装busybox 源码下载地址:http ...

  6. matlab norm的使用

    格式:n=norm(A,p)功能:norm函数可计算几种不同类型的矩阵范数,根据p的不同可得到不同的范数 以下是Matlab中help norm 的解释 NORM Matrix or vector n ...

  7. AttributeError: 'dict_values' object has no attribute 'translate'

    /***************************************************************************************** * Attribu ...

  8. 使用SCP在命令行传输文件

    下载远程服务器上的文件 scp   root@10.0.10.10:/home/user/download.txt  ./download.txt 上传文件到远程服务器 scp  ./upload.t ...

  9. LeetCode Maximum Subarray (最大子段和)

    题意: 给一个序列,求至少含一个元素的最大子段和? 思路: 跟求普通的最大子段和差不多,只不过需要注意一下顺序.由于至少需要一个元素,所以先将ans=nums[0].接下来可以用sum求和了,如果小于 ...

  10. web app 变革之rem

    rem这是个低调的css单位,近一两年开始崭露头角,有许多同学对rem的评价不一,有的在尝试使用,有的在使用过程中遇到坑就弃用了.但是我对rem综合评价是用来做web app它绝对是最合适的人选之一. ...