java_linear list
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的更多相关文章
随机推荐
- 理解NSAttributedString
An NSAttributedString object manages character strings and associated sets of attributes (for exampl ...
- Errors
Errors running builder 'Android Resource Manager' on project 'Demo'. java.lang.NullPointerException ...
- (spring-第5回【IoC基础篇】)spring容器从加载配置文件到实例化bean的内部工作机制
前面讲过,spring的生命周期为:实例化前奏-->实例化-->实例化后期-->初始化前期-->初始化-->初始化后期-->bean的具体调用-->销毁前-- ...
- 几种判断asp.net中session过期方法的比较
方法一:最麻烦也是最容易想到的方法,在每个页面的page_load()方法里面判断: protected void Page_Load(object sender, EventArgs e) { if ...
- 使用busybox构建根文件系统
当我们在Qemu上运行起来自己编译的内核之后,需要使用busybox构建一个文件系统,将此文件系统挂载上去就可以使用busybox提供的各种命令了. 1.编译安装busybox 源码下载地址:http ...
- matlab norm的使用
格式:n=norm(A,p)功能:norm函数可计算几种不同类型的矩阵范数,根据p的不同可得到不同的范数 以下是Matlab中help norm 的解释 NORM Matrix or vector n ...
- AttributeError: 'dict_values' object has no attribute 'translate'
/***************************************************************************************** * Attribu ...
- 使用SCP在命令行传输文件
下载远程服务器上的文件 scp root@10.0.10.10:/home/user/download.txt ./download.txt 上传文件到远程服务器 scp ./upload.t ...
- LeetCode Maximum Subarray (最大子段和)
题意: 给一个序列,求至少含一个元素的最大子段和? 思路: 跟求普通的最大子段和差不多,只不过需要注意一下顺序.由于至少需要一个元素,所以先将ans=nums[0].接下来可以用sum求和了,如果小于 ...
- web app 变革之rem
rem这是个低调的css单位,近一两年开始崭露头角,有许多同学对rem的评价不一,有的在尝试使用,有的在使用过程中遇到坑就弃用了.但是我对rem综合评价是用来做web app它绝对是最合适的人选之一. ...