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