Java基础复习笔记04数据结构线性表.docx
- 文档编号:6649534
- 上传时间:2023-01-08
- 格式:DOCX
- 页数:20
- 大小:52.13KB
Java基础复习笔记04数据结构线性表.docx
《Java基础复习笔记04数据结构线性表.docx》由会员分享,可在线阅读,更多相关《Java基础复习笔记04数据结构线性表.docx(20页珍藏版)》请在冰豆网上搜索。
Java基础复习笔记04数据结构线性表
Java基础复习笔记04数据结构-线性表
刘岩
Email:
suhuanzheng7784877@
1.线性表
线性表是数据结构的一种逻辑结构,其实所有的逻辑数据结构都可以用2类物理实现方式去实现,一个是物理存储连续的顺序结构,另一个就是物理存储不连续的链式结构。
线性表是指有n个元素组成的有序序列,这n个元素具有相同的结构。
2.线性表的操作
线性表的主要操作是增加元素、删除索引处元素、在索引处添加元素、查找索引处元素、替换索引处元素、清空所有元素。
而对于顺序结构和链表结构这两种不同实现方式,底层的算法也会有比较大的差异。
3.使用场景
其实线性表的使用场景非常多,从宏观来说,比如我们从数据库查询多条记录出来需要封装一个集合List对象来承载着众多的业务Bean元素,之后传给MVC的控制C层。
之后C层在以某种展现形式传给视图V层。
那么装载着众多业务记录信息的容器就是线性表。
从微观上来讲,比如实现数据结构的栈结构、或者是对象池的底层、有序排序的数据域等等比较复杂的结构,底层都是离不开线性表的支持。
4.线性表的顺序实现——顺序表
顺序的存储结构实质上就是利用数组进行元素的存储,笔者简单地实现了一个顺序链表。
线性表的顺序实现就是利用对象数组。
看如下代码
packagedateStructer.list;
/**
*自实现的arrayList
*@authorliuyan
*
*@param
*/
publicclassMyArrayList
//默认的数组长度
privatefinalintDefSize=16;
//临时变量数组
privateObject[]objects;
//记录实实在在的元素个数
privateintelementSize;
publicMyArrayList(){
objects=newObject[DefSize];
}
/**
*增加元素,实际上就是往最后一位出入数据
*/
@Override
publicbooleanadd(Ee){
add(elementSize,e);
returntrue;
}
/**
*按位索引插入元素
*/
@Override
publicvoidadd(intindex,Eelement){
if(index==elementSize){
objects[index]=element;
elementSize++;
return;
}
for(inti=elementSize-1;i>=0;i--){
if(i==index){
intmovedSize=elementSize-i-1;
System.arraycopy(objects,index+1,objects,index,movedSize);
objects[index]=element;
elementSize++;
}
}
}
/**
*清除所有元素
*/
@Override
publicvoidclear(){
for(inti=0;i objects[i]=0; } elementSize=0; } /** *判断集合是否包含了某个元素 */ @Override publicbooleancontains(Objecto){ for(Objectobject: objects){ if(object! =null&&object.equals(o)){ returntrue; } } returnfalse; } /** *获得某位置索引的元素 */ @Override publicEget(intindex){ for(inti=0;i if(i==index){ return(E)objects[index]; } } returnnull; } /** *实现元素定位 */ @Override publicintindexOf(Objecto){ for(inti=0;i if(o.equals(objects[i])){ returni; } } return-1; } /** *是否是空集合 */ @Override publicbooleanisEmpty(){ if(elementSize==0){ returntrue; } returnfalse; } @Override publicintlastIndexOf(Objecto){ if(objects==null||objects.length==0){ return-1; } for(inti=elementSize-1;i>=0;i--){ if(objects[i]==o){ returni; } } return-1; } /** *删除某个元素 */ @Override publicbooleanremove(Objecto){ for(inti=0;i if(o.equals(objects[i])){ objects[i]=null; intmovedSize=elementSize-i-1; System.arraycopy(objects,i+1,objects,i,movedSize); elementSize--; returntrue; } } returnfalse; } /** *删除某个索引下的元素 */ @Override publicEremove(intindex){ for(inti=0;i if(objects[i].equals(objects[index])){ objects[i]=null; intmovedSize=elementSize-i-1; System.arraycopy(objects,i+1,objects,i,movedSize); elementSize--; return(E)objects[index]; } } returnnull; } /** *对已有位置设置新的元素值 */ @Override publicEset(intindex,Eelement){ for(inti=0;i if(i==index){ objects[index]=null; objects[index]=element; returnelement; } } returnnull; } @Override publicintsize(){ //TODOAuto-generatedmethodstub returnelementSize; } @Override publicStringtoString(){ StringBufferstr=newStringBuffer("["); for(inti=0;i str.append("["+objects[i].toString()+"],"); } if(elementSize>0){ returnstr.substring(0,str.lastIndexOf(","))+"]"; } returnstr.append("]").toString(); } 实际上实现Java标准的List接口还需要实现其他一些方法,只不过因为篇幅原因,在此只能实现一些核心方法,而且说实在的,根本谈不上健壮性,更不可能投入使用,线程安全也存在问题,这只是演示一下用数组实现顺序线性表的核心算法罢了。 所以说学习数据结构实际上是考验算法功底。 一个数据结构的事先是否最优,完全是底层算法的实现是否最优。 顺序线性表最大的特点就是物理上存储空间连续,内存资源使用比较节省、但是进行增加、删除元素的时候就得让别的元素挪挪地方了,用时间换取了空间的连续性,显得有点牵一发而动全身。 如果是查找某个元素操作的时候就是需要遍历整体集合。 简单测试代码如下: publicstaticvoidmain(String[]args){ MyArrayList list.add("1"); list.add("2"); list.add("3"); System.out.println(list); list.remove("3"); System.out.println(list); list.add("3"); System.out.println(list); System.out.println(list.contains("2")); System.out.println(list.isEmpty()); list.clear(); System.out.println(list); System.out.println(list.isEmpty()); } 执行结果 [[1],[2],[3]] [[1],[2]] [[1],[2],[3]] true false [] true 5.线性表的非顺序实现——链式表 相对于数组的顺序存储,还可以定义一个比较特殊的链表结构,每个链表节点在内存中不一定是一块连续的区域,链表节点记录了与自身节点相关的下一个节点的位置信息。 如果链表节点仅仅记录了与其下一个Next节点的位置信息,而没有记录上一个Prev节点的信息,那么这叫做单向链表结构。 如果此节点不仅仅记录了下一个节点的信息,还记录了上一个节点的信息,那么这个情况叫做双向链表结构。 我们就用双向链表实现Java标准的List (实际上Java提出了一堆标准,实际上就是接口,而sun自己为自己定义的标准接口还提供了实现类,咱们一般用的就是基于sun提出标准的sun自己的实现类)。 如下代码 /** *自己实现的linkedList *@authorliuyan *@param */ publicclassMyLinkedList /** *双向链表结构 */ publicclassLinkNode{ //真正的数据域 privateEdate; //记录上一个节点 privateLinkNodeprevLinkNode; //记录下一个节点 privateLinkNodenextLinkNode; publicLinkNode(){ } publicLinkNode(Edate,LinkNodeprevLinkNode,LinkNodenextLinkNode){ this.date=date; this.prevLinkNode=prevLinkNode; this.nextLinkNode=nextLinkNode; } } //结点个数 privateintnodeSize; //头结点 privateLinkNodeheadNode; //尾巴节点 privateLinkNodetailNode; publicMyLinkedList(){ headNode=null; tailNode=null; } /** *采用尾端元素增加法,增加新元素 */ @Override publicbooleanadd(Eelement){ if(nodeSize==0){ headNode=newLinkNode(element,null,tailNode); }else{ if(tailNode==null){ tailNode=newLinkNode(element,headNode,null); headNode.nextLinkNode=tailNode; nodeSize++; returntrue; } LinkNodelinkNode=tailNode; tailNode=newLinkNode(element,linkNode,null); linkNode.nextLinkNode=tailNode; } nodeSize++; returntrue; } /** *根据索引号查找节点 * *@paramindex *@return */ publicLinkNodefindLinkNodeByIndex(intindex){ LinkNodelinkNodeNowTemp=headNode; for(inti=0;i if(i==index){ returnlinkNodeNowTemp; } linkNodeNowTemp=linkNodeNowTemp.nextLinkNode; } returnnull; } /** *按索引位置添加元素 */ @Override publicvoidadd(intindex,Eelement){ if(nodeSize==0){ add(element); } //按照元素先建立新的node LinkNodelinkNodeNew=newLinkNode(element,null,null); //找到索引处的节点 LinkNodelinkNodeNowTemp=findLinkNodeByIndex(index); //找出索引处节点的上一个node LinkNodelinkNodePrev=linkNodeNowTemp.prevLinkNode; //上一个节点的下一个节点指向新node linkNodePrev.nextLinkNode=linkNodeNew; //新节点的上一个节点指向原位置节点上一个节点 linkNodeNew.prevLinkNode=linkNodePrev; //新节点的下一个节点指向原位置节点 linkNodeNew.nextLinkNode=linkNodeNowTemp; //原节点的上一个节点指向新节点 linkNodeNowTemp.prevLinkNode=linkNodeNew; nodeSize++; } /** *清除所有Node元素资源 */ @Override publicvoidclear(){ LinkNodelinkNodeNowTemp=headNode; for(inti=0;i if(linkNodeNowTemp! =tailNode&&linkNodeNowTemp! =headNode){ linkNodeNowTemp=linkNodeNowTemp.nextLinkNode; linkNodeNowTemp.prevLinkNode.nextLinkNode=null; linkNodeNowTemp.prevLinkNode.prevLinkNode=null; linkNodeNowTemp.prevLinkNode.date=null; linkNodeNowTemp.prevLinkNode=null; }elseif(linkNodeNowTemp==tailNode){ linkNodeNowTemp.prevLinkNode=null; }elseif(linkNodeNowTemp==headNode){ linkNodeNowTemp.nextLinkNode=null; } } headNode=null; tailNode=null; nodeSize=0; } /** *是否包含此元素 */ @Override publicbooleancontains(Objectobject){ LinkNodelinkNodeNowTemp=headNode; for(inti=0;i if(object==linkNodeNowTemp.date){ returntrue; } linkNodeNowTemp=linkNodeNowTemp.nextLinkNode; } returnfalse; } @Override publicEget(intindex){ LinkNodelinkNode=findLinkNodeByIndex(index); if(linkNode! =null){ returnlinkNode.date; } returnnull; } @Override publicbooleanisEmpty(){ returnnodeSize==0; } /** *删除元素 */ @Override publicbooleanremove(Objecto){ LinkNodelinkNodeNowTemp=headNode; for(inti=0;i if(linkNodeNowTemp.date==o){ if(linkNodeNowTemp! =tailNode&&linkNodeNowTemp! =headNode){ LinkNodelinkNewPrev=linkNodeNowTemp.prevLinkNode; LinkNodelinkNewNext=linkNodeNowTemp.nextLinkNode; linkNewPrev.nextLinkNode=linkNewNext; linkNewNext.prevLinkNode=linkNewPrev; linkNodeNowTemp.nextLinkNode=null; linkNodeNowTemp.prevLinkNode=null; linkNodeNowTemp.date=null; linkNodeNowTemp=null; nodeSize--; returntrue; }elseif(linkNodeNowTemp==tailNode){ tailNode=linkNodeNowTemp.prevLinkNode; linkNodeNowTemp.prevLinkNode=null; linkNodeNowTemp.date=null; linkNodeNowTemp=null; nodeSize--; returntrue; }elseif(linkNodeNowTemp==headNode){ headNode=linkNodeNowTemp.nextLinkNode; linkNodeNowTemp.nextLinkNode=null; linkNodeNowTemp.date=null; linkNodeNowTemp=null; nodeSize--; returntrue; } } linkNodeNowTemp=linkNodeNowTemp.nextLinkNode; } returnfalse; } /** *删除位置标记下的元素 */ @Override publicEremove(intindex){ LinkNodelinkNodeNowTemp=headNode; for(inti=0;i if(index==i){ LinkNodelinkNewPrev=linkNodeNowTemp.prevLinkNode;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java 基础 复习 笔记 04 数据结构 线性