码迷,mamicode.com
首页 > 编程语言 > 详细

算法系列(六)数据结构之表队列和栈

时间:2016-06-04 08:08:53      阅读:245      评论:0      收藏:0      [点我收藏+]

标签:

在http://blog.csdn.net/robertcpp/article/details/51559333一文中,我们讲了排序,这一章来介绍一下基本数据结构:表、队列、栈和它们的简单实现

一、表ADT

1、数组实现顺序表

通过对数组操作,来直接对表进行增删查改操作,这种线性表查找某个位置的元素花费的时间为O(1),但是插入删除元素花费的时间为O(n),如果对表的操作更多的是访问操作,那么选择这种实现更为合适。
下面是一个简单实现
package com.algorithm.list;

import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * 线性数组
 * 
 * @author chao
 *
 * @param <E>
 */
public class MyArrayList<E> implements Iterable<E> {
	private static final int DEFAULT_CAPACITY = 10;
	private int theSize;
	private E[] theItems;

	public MyArrayList() {
		clear();
	}

	public void clear() {
		theSize = 0;
		ensureCapacity(DEFAULT_CAPACITY);
	}

	public void ensureCapacity(int newCapacity) {
		if (newCapacity < theSize) {
			return;
		}
		E[] oldEs = theItems;
		theItems = (E[]) new Object[newCapacity];
		for (int i = 0; i < theSize; i++) {
			theItems[i] = oldEs[i];
		}

	}

	public int size() {
		return theSize;
	}

	public void trimToSize() {
		ensureCapacity(size());
	}

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

	public E get(int index) {
		if (index < 0 || index > theSize) {
			throw new ArrayIndexOutOfBoundsException();
		}
		return theItems[index];

	}

	public E set(int index, E newval) {
		if (index < 0 || index >= theSize) {
			throw new ArrayIndexOutOfBoundsException();
		}
		E oldvallue = theItems[index];
		theItems[index] = newval;
		return oldvallue;
	}

	@Override
	public Iterator<E> iterator() {
		return new ArraylistIterator();
	}

	public boolean add(E value) {
		add(size(), value);
		return true;
	}

	public void add(int index, E value) {
		if (theItems.length == theSize) {
			ensureCapacity(theSize * 2 + 1);
		}
		for (int i = theSize; i > index; i--) {
			theItems[i] = theItems[i - 1];
		}
		theItems[index] = value;
		theSize++;
	}

	public E remove(int index) {
		E oldvalue = theItems[index];
		for (int i = index; i < theSize; i++) {
			theItems[i] = theItems[i + 1];
		}
		theSize--;
		return oldvalue;
	}

	class ArraylistIterator<E> implements Iterator<E> {
		private int current = 0;

		@Override
		public boolean hasNext() {
			return current < theSize;
		}

		@Override
		public E next() {
			if (!hasNext()) {
				throw new NoSuchElementException();
			}
			return (E) theItems[current++];
		}

		@Override
		public void remove() {
			MyArrayList.this.remove(--current);
		}

	}
}
2、链表
链表是一种插入删除操作时间复杂度为O(1)的数据结构,但是访问操作的时间复杂度为O(n)
下面是我们的简单实现
package com.algorithm.list;

import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * 链表数据结构
 * 
 * @author chao
 *
 * @param <E>
 */
public class MyLinkedList<E> implements Iterable<E> {
	private class Node<T> {
		public Node() {

		}

		public Node(T ele, Node next, Node pre) {
			this.ele = ele;
			this.next = next;
			this.pre = pre;
		}

		T ele;
		Node next;
		Node pre;
	}

	private Node<E> head;
	private Node<E> tail;
	private int size;
	private int modcount = 0;

	public MyLinkedList() {
		clear();
	}

	public void clear() {
		head = new Node<E>(null, null, null);
		tail = new Node<E>(null, head, null);
		head.next = tail;
		size = 0;
		modcount++;

	}

	@Override
	public Iterator<E> iterator() {
		return new LinkedListIterator();
	}

	private class LinkedListIterator implements Iterator<E> {
		private Node<E> current = head.next;
		private boolean okToremove = false;
		private int expectedModcount = modcount;

		@Override
		public boolean hasNext() {
			return current != tail;
		}

		@Override
		public E next() {
			if (modcount != expectedModcount) {
				throw new ConcurrentModificationException();
			} else if (!hasNext()) {
				throw new NoSuchElementException();
			}
			current = current.next;
			okToremove = true;
			return (E) current.pre.ele;
		}

		@Override
		public void remove() {
			if (!okToremove) {
				throw new IllegalStateException();
			} else if (modcount != expectedModcount) {
				throw new ConcurrentModificationException();
			}
			MyLinkedList.this.remove(current.pre);
			okToremove = false;
			expectedModcount++;
		}
	}

	public boolean isempty() {
		return size == 0;
	}

	public int size() {
		return size;
	}

	private Node getNode(int index) {
		if (index < 0 || index >= size) {
			throw new IndexOutOfBoundsException();
		}
		Node<E> p = null;
		if (index < size / 2) {
			p = head.next;
			for (int i = 0; i < index; i++)
				p = p.next;
		} else {
			p = tail;
			for (int i = size; i > index; i--)
				p = p.pre;
		}
		return p;
	}

	public E get(int index) {
		return (E) getNode(index).ele;
	}

	private E remove(Node node) {
		node.next.pre = node.pre;
		node.pre.next = node.next;
		size--;
		modcount++;
		return (E) node.ele;
	}

	public E remove(int index) {
		return remove(getNode(index));
	}

	public void add(int index, E ele) {
		addBefore(getNode(index), ele);
	}

	private void addBefore(Node node, E ele) {
		Node newnode = new Node<E>(ele, node.pre, node);
		node.pre.next = newnode;
		node.pre = newnode;
		size++;
		modcount++;
	}

	public void add(E ele) {
		add(size, ele);
	}
}

三、队列数据结构

队列是一种先进先出的数据结构FIFO
有两种实现方式,一种是链表实现,一种是数组实现。跟刚才讲的表的实现一样的,只是在表的基础上加了限制,
每次只能在表的末尾增加新元素,访问元素只能从表头访问。
技术分享
线程池中有线程队列,消息池中有消息队列,实际应用中通常会对队列中的元素添加优先级,那种队列叫做优先队列,后期会做单独分析。

四、栈的数据结构

栈是一种后进先出的数据结构LIFO
跟队列一样,栈也有两种实现方式,数组实现跟链表实现。在表的基础上加了限制,
每次只能在表的末尾新增元素,访问元素也只能从表的末尾

技术分享
栈是计算机术语中比较重要的概念,实质上栈就是一段内存区域,但是栈满足一定的特性,那就是只有一个口,具有先入后出的特性,这种特性在计算机中有很广泛的运用。其实在程序员无时无刻不在运用栈,函数的调用是我们间接使用栈的最好例子,因此可以说栈的一个最重要的运用就是函数的调用。但是栈的运用还不止这些,还有很多,其中几个典型的运行如下:判断平衡符号,实现表达式的求值(也就是中缀表达式转后缀表达式的问题以及后缀表达式求值问题),在路劲探索中实现路劲的保存也可以说是栈的经典运用之一。
队列和和栈的两种实现请参考我的github地址https://github.com/robertjc/simplealgorithm


github代码也在不断完善中,有些地方可能有问题,还请多指教

欢迎扫描二维码,关注公众账号
技术分享


算法系列(六)数据结构之表队列和栈

标签:

原文地址:http://blog.csdn.net/robertcpp/article/details/51582292

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!