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. hello iic

    刚刚终于弄出来了这个.发现自己很多问题. 一 mian函数 #include "led.h"#include "delay.h"#include "s ...

  2. (转)tomcat与地址栏图标之研究(多浏览器)

    原文:http://hi.baidu.com/hebo_thu/item/fc8c81bb164f5cee4fc7fd90 tomcat与地址栏图标之研究(多浏览器) 最近在做一个java网络应用程序 ...

  3. hdu 2082

    ps:get到了母函数...看了好久的模板与介绍....似懂非懂..决定要多找些题来试试... 代码: #include "stdio.h" #include "stri ...

  4. 多比Web 3D展示(3D机房/3D监控)中间件多比Web 3D展示(3D机房/3D监控)中间件免费下载购买地址

    多比3D是实现3D场景搭建的软件开发包,可以创建广泛的3D应用,适用于高端制造.能源.国防军工.教育科研.城市规划及建筑环艺.生物医学等领域的虚拟仿真,应用于虚拟展示.虚拟设计.方案评审.虚拟装配.虚 ...

  5. BZOJ 1816 扑克牌

    WA的我怀疑人生.. 发现原来是循环中间就要break掉,不然爆int. 总感觉这题可以直接构造啊.. #include<iostream> #include<cstdio> ...

  6. HDU 5862(离散化+树状数组)

    Problem Counting Intersections 题目大意 给定n条水平或竖直的线段,统计所有线段的交点个数. (n<=100000) 解题分析 首先将线段离散化. 然后将所有线段按 ...

  7. CentOS 6.6 FTP install

    /************************************************************************* * CentOS 6.6 FTP install ...

  8. 【题解】【区间】【二分查找】【Leetcode】Insert Interval & Merge Intervals

    Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessa ...

  9. CSS table-layout 、border-collapse属性

    ( table-layout)设置表格布局算法: 可能的值 值 描述 automatic 默认.列宽度由单元格内容设定. fixed 列宽由表格宽度和列宽度设定. inherit 规定应该从父元素继承 ...

  10. ZOJ 1089 Lotto

    原题链接 题目大意:有一种抽奖游戏乐透(Lotto),规则是从1到49这49个自然数中随机抽取6个数.现在有一种简化版的游戏,先在49个数里面选出k(6<k<13)个数,然后再从这k个数里 ...