Java数据结构(一)

Java数据结构(一)

——线性表

线性表(亦作顺序表)是最基本、最简单、也是最常用的一种数据结构。线性表的主要特点是,可以在任意位置插入一个数据元素或删除一个数据元素。线性表可以用顺序存储结构或链式存储结构实现,使用顺序存储结构实现的线性表称为顺序表,而使用链式存储结构实现的称为链表,链表主要有单链表,循环单链表,双向链表等。在本篇博客中主要介绍实现的是顺序表与单链表两种。

?

?

顺序表

package pzw.List;

/**
 * 利用线性表接口实现顺序表类
 * @author PZW
 *
 */
public class SeqList implements List{
	//设置默认构造的顺序表长度
	final int defaultSize = 10;
	
	int maxSize;
	int size;
	Object[] listArray;
	//无参构造函数
	public SeqList(){
		initiate(defaultSize);
	}
	//构造函数
	public SeqList(int size){
		initiate(size);
	}
	//初始化顺序表
	private void initiate(int sz){
		maxSize = sz;
		size = 0;
		listArray = new Object[sz];
	}
	
	public void insert(int i, Object elm) throws Exception {
		if(size == maxSize){
			throw new Exception("顺序表已满无法插入");
		}
		if(i < 0||i > size){
			throw new Exception("输入的插入位置错误");
		}
		for(int j = size;j > i;j--){
			listArray[j] = listArray[j-1];
		}
		listArray[i] = elm;
		size++;
	}
	
	public void append(Object elm) throws Exception{
		insert(size,elm);
	}

	@Override
	public Object delete(int i) throws Exception {
		if(size == 0){
			throw new Exception("顺序表已空无法删除");
		}
		if(i < 0||i > size){
			throw new Exception("输入的删除位置错误");
		}
		Object elm = listArray[i];
		for(int j = i;j < size -1;j++){
			listArray[j] = listArray[j+1];
		}
		size--;
		return elm;
	}


	public Object getData(int i) throws Exception {
		if(i < 0||i > size){
			throw new Exception("参数错误");
		}
		return listArray[i];
	}
	
	public void print(){
		for(int i = 0;i < size;i++){
			System.out.print(listArray[i]+"  ");
		}
		System.out.println();
	}

	@Override
	public int size() {
		// TODO Auto-generated method stub
		return size;
	}

	@Override
	public boolean isEmpty() {
		// TODO Auto-generated method stub
		return size == 0;
	}
	
	/**
	 * 
	 * @param sl
	 * @param elm
	 * @return
	 * @throws Exception
	 */
	public int MoreDataDelete(SeqList sl,Object elm) throws Exception{
		int i,j;
		int tag = 0;
		for(i = 0;i < sl.size;i++){
			if(elm.equals(sl.getData(i))){
				sl.delete(i);
				i--;
				tag = 1;
			}
		}
		return tag;
	}

}

? ? ? ? 顺序表的主要优点是:支持随机读取,以及内存空间利用效率高;

? ? ? ? 顺序表的主要缺点是:需要预先给出数组的最大数据元素个数,但数组的最大数据元素个数很难准确给出。另外,插入和删除操作每次都必须要遍历数组,即使是在平均情况下,插入和删除操作的时间代价也是O(n)。

单链表

package pzw.list;

/**
 *自定义链表一共由两个类组成
 *链表类的方法、属性
 * @author pzw
 *
 */
public class JList {
	
	//定义一个头指针
	private JListNode head = null;
	
	//创建一个新的节点
	JListNode flag=new JListNode();
	
	//记录链表中元素的个数
	private int nCount = 0;
	
	//插入方法(默认插在最后)
	public void add(JListNode node){
		add(node,nCount);
		
	}
	
	//插入方法(从nPos位置插入)
	public void add(JListNode node,int nPos){
		//判断位置是否输入正确
		if(nPos<0||nPos>nCount){
			System.out.println("插入的位置错误");
			return;
		}
		
		//如果链表为空,将头节点指向node
		if(nCount==0){
			head=node;
			nCount++;
			return;
			
		}
		
		//其他情况
		//创建一个新的节点来指向head
		flag=head;
		
		//找到要插入的点的上一个节点
		for(int i=0;i<nPos-1;i++){
			//将flag指向flag的下一个节点
			flag=flag.Next;
		}
		
		//将插入的元素与其他元素链接起来
		node.Next=flag.Next;
		flag.Next=node;
		
		nCount++;
		
	}
	
	//删除一个元素(链表默认从头删除)
	public JListNode delete(){
		return delete(0);
	}
	
	//删除一个元素(将元素从指定的nPos位置删除)
	public JListNode delete(int nPos){
		//如果链表为空
		if(nCount==0){
			System.out.println("该链表为空");
			return null;
		}
		
		
		//如果链表中只有一个元素
		if(nCount==1){
			flag=head;
			head=null;
			nCount=0;
			return flag;
		}
		
		//判断输入的位置是否正确
		if(nPos<0||nPos>nCount-1){
			System.out.println("删除的位置错误");
			return null;
		}
		
		//如果nPos为零
		if(nPos==0){
			flag=head;
			head=head.Next;
			flag.Next=null;
			nCount--;
			return flag;
		}
		
		//其他情况
		flag=head;
		//找到要删除位置的元素的前一个
		for(int i=0;i<nPos-1;i++){
			flag=flag.Next;
		}
		
		//记录flag的下一个节点
		JListNode temp=flag.Next;
		flag.Next=temp.Next;
		temp.Next=null;
		nCount--;
		
		return temp;
	}
	
	//删除链表中所有元素
	public void remove(){
		for(int i=0;i<nCount-1;i++){
			this.delete();
		}
	}
	
	//得到指定位置nPos的元素的值(返回一个节点)
	public JListNode get(int nPos){
		flag=head;
		//找到要输出的那个节点
		for(int i=0;i<nPos;i++){
			flag=flag.Next;
		}
		
		//使用temp复制flag节点,但让temp的Next指向空
		JListNode temp=new JListNode();
		//temp=flag;
		temp.nValue=flag.nValue;
		temp.Next=null;
		
		return temp;
	}
	
	//获取链表中一共有多少个元素
	public int size(){
		return nCount;
	}
	
}

? ? ? ?单链表的主要优点是不需要预先给出数据元素的最大个数。另外单链表插入和删除工作时不需要移动数据元素。

? ? ? ?单链表的主要缺点是每个节点中要有一个指针,因此单链表的空间利用率低于顺序表,另外,单链表不支持随机读取,单链表的读取必须从头结点开始遍历,因此单链表读取数据的时间代价是O(n)。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。