【JAVA】数据结构与算法

第一章:表、栈和队列

时间复杂度

描述的代码的执行效率,表示为O(n)的函数。

线性结构和非线性结构

线性结构
1.数据元素之间存在一对一的关系
2.数据有两种存储结构:顺序存储结构(顺序表)和链式存储结构(链表)。
3.线性结构:数组、队列、链表和栈

** 非线性结构**
非线性结构:数据元素之间不一定是一对一的线性关系;二维数组,多维数组,广义表,树结构,图结构

List接口、ArrayList类和LinkedList类

关系图:

interface Collection implements Iterator
interface List implements Collection 
class ArrayLsitList implements List
class LinkedList implements List

ArrayList的是用可增长数组实现的,优点在于对get和set的调用花费常数时间,缺点是对于插入和删除元素代价昂贵,因为数组元素的存储结构是连续的,且相对位置和数组下标相对应。插入和删除元素都需要把特定位置之后的元素向前或者向后挪移。

LinkedList是双向链表,优点在于:假设变动项的位置是已知的,插入和删除开销很小;但是其没有下标索引,所以get的调用比较费时间。

MyArrayList

ArrayList是数组结构进行操作数据,里面包含一个容器容量的概念。下面看实现代码!

ArrayList包含对数据的基本操作:清空元素,删除元素,查看容器是否为空,添加元素,迭代器等等。各种操作是基于数组结构进行操作的。

import java.util.Iterator;
/* size()
 * add()
 * remove()
 * capacity() 
 */
public class MyArrayList<AnyType> implements Iterator {	
	//默认容器长度
	private static final int DEFAULT_CAPACITY=10;
	
	//数组长度
	private int thesize;
	
	//定义数组
	private AnyType[] element;	
	
	public MyArrayList() {
		doclear();
	}
	
	//判断是否为空
	public boolean isEmpty() {
		return thesize==0;
	}
	
	//清空容器
	public void doclear() {
		thesize=0;ensureCapacity(DEFAULT_CAPACITY);
	}
	
	//返回数组长度
	public int size() {
		return thesize;
	}
	//获取指定位置上的元素
	public AnyType get(int index) {
		if(index<0||index>size()) {
			throw new ArrayIndexOutOfBoundsException();
		}
		return element[index];
	}
	//把index位置上值替换掉,并且返回被替换掉的值
	public AnyType set(int index,AnyType val) {
		if(index<0||index>size()) {
			throw new ArrayIndexOutOfBoundsException();
		}
		AnyType oldelement=element[index];
		element[index]=val;
		return oldelement;
	}
	
	//修改容器的承载能力
	@SuppressWarnings("unchecked")
	public void ensureCapacity(int capacity) {
		if(thesize<capacity) 
			return;
		AnyType[] oldelement=element;
		element=(AnyType[]) new Object[capacity];
		for(int i=0;i<thesize;i++) {
			element[i]=oldelement[i];
		}		
	}
		
	//添加元素
	public boolean add(AnyType val) {
		add(size(),val);
		return true;
	}
	
	//在index位置添加元素
	private void add(int index, AnyType val) {
		if(index<0||index>thesize) {
			throw new ArrayIndexOutOfBoundsException();
		}
		if(element.length==size()) {
			ensureCapacity(thesize*2+1);
		}
		for(int i=thesize;i>index;i--) {
			element[i]=element[i-1];
		}
		element[index]=val;
		thesize++;
	}
	
	//移除index位置上的元素,并返回被移除的值
	public AnyType remove(int index) {
		if(index<0||index>size()) {
			throw new ArrayIndexOutOfBoundsException();	
		}
		AnyType removeelement=element[index];
		for(int i=index;i<thesize-1;i++) {
			element[i]=element[i++];
		}
		thesize--;	
		return removeelement;	
	}
	
	public java.util.Iterator<AnyType> iterator(){
		return this.new ArrayListIterator();//这里面省略了一个this
	}
		
	private class ArrayListIterator implements java.util.Iterator<AnyType>{
		
		private int current=0;
			
		@Override
		public boolean hasNext() {
			if(current<size()) {
				return true;
			}
			return false;
		}

		@Override
		public AnyType next() {
			// TODO Auto-generated method stub
			if(!hasNext()) {
				throw new java.util.NoSuchElementException();
			}
			return element[current++];
		}
		
		public void remove() {
			MyArrayList.this.remove(--current);
		}
		
	}

	@Override
	public boolean hasNext() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public Object next() {
		// TODO Auto-generated method stub
		return null;
	}
}

MyLInkedList

LinkedList是双链表。

/*
 * 和单边二叉树有点像
 */
public class MyLinkedList<AnyType> implements Iterator<AnyType> {
	private Node<AnyType> beginMarker;
	private Node<AnyType> endMarker;
	private int modCount=0;
	private int theSize;
	
	//初始化
	public MyLinkedList() {
		doclear();
	}
	
	private void doclear() {
		beginMarker=new Node<AnyType>(null,null,null);
		endMarker=new Node<AnyType>(null,beginMarker,null);
		beginMarker.next=endMarker;
		modCount++;
		theSize=0;
	}
	//重新初始化文件
	public void clear() {
		doclear();
	}
	
	public void addBefore(Node<AnyType> p,AnyType x) {
		//这就创建一个新的节点
		Node<AnyType> newnode=new Node<AnyType>(x,p.prev,p);
		p.prev.next=newnode;
		p.prev=newnode;
		theSize++;
		modCount++;		
	}
	
	public int size() {
		return theSize;
	}
	public boolean add(AnyType x) {
		add(size(),x);
		return true;
	}
		
	private void add(int index, AnyType x) {
		// TODO Auto-generated method stub
		addBefore(getNode(index,0,size()),x);		
	}

	public AnyType remove(int index) {
		return remove(getNode(index));		
	}
	
	public AnyType get(int index) {
		return getNode(index).data;
	}
	
	//删除节点,并返回删除节点的值
	public AnyType remove(Node<AnyType> node) {		
		node.next.prev=node.prev;
		node.prev.next=node.next;
		theSize--;
		modCount++;
		return node.data;
	}
	
	private Node<AnyType> getNode(int index) {		
		return getNode(index,0,size()-1);
	}
		
	public Node<AnyType> getNode(int index,int lower,int upper) {
		Node<AnyType> p;
		if(index<lower||index>upper) {
			throw new IndexOutOfBoundsException();
		}		
		if(index<size()/2) {
			p=beginMarker.next;
			for(int i=0;i<index;i++) {
				p=p.next;
			}			
		}else {
			p=endMarker;
			for(int i=size();i>index;i--) {
				p=p.prev;
			}
		}		
		return p;		
	}
	
	public java.util.Iterator<AnyType> iterator(){
		return new LinkedListIterator();
	}
	
	private class LinkedListIterator implements java.util.Iterator<AnyType>{
		private Node<AnyType> currentnode=beginMarker.next;
		private int modcount=modCount;
		private boolean okToRemove=false;
		
		@Override
		public boolean hasNext() {
			return currentnode!=endMarker;
		}

		@Override
		public AnyType next() {
			if(modCount!=modcount) {
				throw new java.util.ConcurrentModificationException();
			}
			if(!hasNext()) {
				throw new java.util.NoSuchElementException();
			}
			AnyType item=currentnode.data;
			currentnode=currentnode.next;
			okToRemove=true;
			return item;
		}
		
		public void remove() {
			if(modCount!=modcount) {
				throw new java.util.ConcurrentModificationException();
			}
			if(!okToRemove) {
				throw new IllegalStateException();
			}
			
			MyLinkedList.this.remove(currentnode.prev);
			modcount++;
			okToRemove=false;
			
		}	
	}
	
	@Override
	public boolean hasNext() {
		// TODO Auto-generated method stub
		return false;
	}
	@Override
	public AnyType next() {
		// TODO Auto-generated method stub
		return null;
	}
		
	//每一个节点的信息
	private static class Node<AnyType>{
		public Node(AnyType d,Node<AnyType> p,Node<AnyType> n) {
			data=d;
			prev=p;
			next=n;			
		}	
		private AnyType data;
		public Node<AnyType> prev;
		public Node<AnyType> next;	
	}
}

栈ADT

class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  
class Stack extends Vector

栈又叫做LIFO(后进先出)表

栈模型: 栈就像一个子弹夹,只有一个口用来插入和输出,并且遵循先进后出的原则。表的末端叫做栈顶。相关操作有:进栈(push)和出栈(pop)。

栈的单链表结构实现 把我给写吐了,我好菜

package link;

import java.util.Iterator;
import java.util.Stack;


public class MyStack<AnyType> {
	//单链表结构实现
	private int size;
	private Node<AnyType> endNode;
	private Node<AnyType> topnode;
	public MyStack() {
		doclear();
		this.endNode=new Node<AnyType>(null,null);
		this.size=0;
	}
	
	public void doclear() {
		// TODO Auto-generated method stub
		endNode=null;	
		size=0;
	}
	
	public int size() {
		return size;
	}

	public Node<AnyType> push(AnyType val) {
		Node<AnyType> newnode=new Node<AnyType>(val,null);
		getnode(size()).pre=newnode;
		size++;
		return null;	
	}
	
	//返回最上面的节点
	public Node getnode(int index) {
		Node<AnyType> p=endNode;
		for(int i=0;i<index;i++) {
			p=p.pre;
		}		
		return p;
	}
	
	//出栈并删除
	public Object pop() {
		if(size==0) {
			return null;
		}
		Node node=getnode(size()-1);
		AnyType val=(AnyType) node.pre.item;
		node.pre=null;
		size-=1;
		return val;
	}
		
	public static void main(String[] args) {
		MyStack<Integer> m=new MyStack<>();
		for(int i=0;i<10;i++) {
			m.push(i);
		}
		for(int i=0;i<5;i++) {
		System.out.println(m.pop()+" "+m.size());
		}
	}
	
	class Node<AnyType>{
		private AnyType item;
		public Node pre;	
		public Node(AnyType item,Node<AnyType> n){
			this.item=item;
			this.pre=n;
		}	
	}
}

代码总结:
利用单向链表去实现栈的数据结构。
首先分析这个MyStack这个类里面应该有什么:节点(表示元素和其他节点的地址),记录总的数据;对数据进行的操作应该有:插入,获取栈顶元素并同时删除栈顶元素,获取表大小
节点该怎么表示呢:节点不是数据结构就行了,它应该是一个箱子(类的比喻),对于MyStack来讲,是对箱子进行操作。箱子这个类有自己的内容,装的是一个元素和一个地址。
上面可以看出:Java是一门面向对象的语言,同时还包含了封装的特点!好好体会!每一个类有自己要做的事情,每一个方法也有自己要做的事情。

栈的数组实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值