p2p网站建设广州,php网站后台页面,网上做广告怎么收费,公司建站费用链表是java数据结构中一种很基础很常见却也很重要的数据结构#xff0c;JDK中许多内置jar包基于单链表实现#xff0c;比如像我们熟悉的linkedList等#xff0c;为什么要使用链表呢#xff1f;
我们知道java中很多集合的底层是基于数组实现的#xff0c;数组有一个很重要…链表是java数据结构中一种很基础很常见却也很重要的数据结构JDK中许多内置jar包基于单链表实现比如像我们熟悉的linkedList等为什么要使用链表呢
我们知道java中很多集合的底层是基于数组实现的数组有一个很重要的结构就是索引通过索引可以快速定位数据并对数据进行删除等操作但问题是我们的业务中数组有自身的局限性如果知道索引还好如果不知道索引就需要一个个遍历查找然后再进行操作假如是删除一个数据对于数组来说要进行的操作是根据索引定位到数据然后删除这条数据然后数组中的数据进行重新位置的移动平均来看这个时间复杂度应该是2logN尤其是重新调整位置使得性能开销较大
我们看看下面这张链表的图 链表的结构很简单就是一个个节点连接在一起形成一个完整的链条每个节点包含2部分数据域和一个指向下一个节点引用的指针next,具体的更详细的大家可以参考相关资料解释再说说删除操作同样需要找到数据所在的位置然后进行删除不同的是删除的时候链表只需要改变一下前后节点的引用关系即可就完成了节点的删除而没有像数组那样触发一次全部数据的移动从这个描述来看链表在进行删除的时候速度比数组快
链表的分类有很多种比如单链表双端链表双向链表单向链表等下面说说单链表的具体实现单链表是其他链表的基础掌握了单链表实现其他的就好理解了下面直接上代码可以结合注释看
class ListNodeT {private int foot; //根节点索引位置private int count; //代表链表程度private Node root; //标识根节点//链接点类,内部方法实现外部使用private class Node{private T data; //数据信息private Node next; //下一个节点引用public Node(T data) {this.data data;}//添加节点private void add(T data){if(this.next null){this.next new Node(data); //如果当前节点的next为null,直接创建一个新的节点}else {this.next.add(data); //否则进行递归调用直到最后在某个为空的节点创建一个新节点}}//删除节点1public void remove(Node previous, int index){if(ListNode.this.foot index){previous.next this.next; //this表示当前要删除的节点this.next null; ListNode.this.count--;return;}else{this.next.remove(this,index); //递归删除}}//删除节点2 public void remove(Node previous, T data){if(this.data.equals(data)){previous.next this.next;this.next null;ListNode.this.count--;return ;}else{if(this.next ! null){this.next.remove(this,data);}else{return;}}}//修改数据 -- 新数据替换旧数据public void replace(T oldData,T newData){if(this.data.equals(newData)){this.data newData;}else{this.next.replace(oldData, newData); //递归修改寻找当前节点下一个节点直到某个节点的值匹配入参}}//修改数据 -- 利用索引修改public void replace(int index,T newData){if(ListNode.this.foot index){ //找到了某个值的索引和传入的索引相同直接替换this.data newData;}else{this.next.replace(index, newData);}}//查询public T get(int index){if(ListNode.this.foot index){return this.data;}else{return this.next.get(index);}}//链表是否包含某个节点public boolean contains(T data){if(this.data.equals(data)){ //如果当前的这个data正好和传入的data匹配return true;}else{//如果当前的这个不匹配则需要查找下一个节点if(this.next null){return false;}else{return this.next.contains(data);}}}}public ListNode() {}//检查链表是否为空public boolean isEmpty(){if(count 0 || this.root null){return true;}else{return false;}}//获取链表的长度public int size(){return this.count;}//添加public void add(T data){if(this.isEmpty()){ //如果链表为空新建一个节点this.root new Node(data);}else{this.root.add(data);}this.count;}//删除 -- 按照索引删除public void remove(int index){if(this.isEmpty()){return;}if(index 0 || this.count index){return ;}if(index 0){ //想要删除根节点Node temp this.root;this.root this.root.next;temp.next null;this.count--;return ;}else{this.foot 0;this.root.remove(this.root, index);}}//根据传入的数值删除public void remove(T data){if(this.isEmpty()){return;}if(this.root.data.equals(data)){ //如果删除的正好是根节点Node temp this.root;this.root this.root.next;temp.next null;this.count--;return ;}else{this.root.remove(this.root, data);}}//修改 -- 根据索引修改public void replace(int index,T newData){if(this.isEmpty()){return;}if(index 0 || this.count index){return ;}this.foot 0;this.root.replace(index, newData);}//修改 -- 新老数据替换public void replace(T oldData,T newData){if(this.isEmpty()){return;}this.root.replace(oldData, newData);}//查询 --- 根据索引查找public T get(int index){if(this.isEmpty()){return null;}this.foot 0;return this.root.get(index);}//是否包含public boolean contains(T data){if(this.isEmpty()){return false;}return this.root.contains(data);}//打印 toArraypublic Object[] toArray(){if(this.isEmpty()){return null;}int count this.count;Object[] retVal new Object[count];for(int i0;icount;i){retVal[i] this.get(i);}return retVal;}
}下面是测试代码
public static void main(String[] args) {ListNodeString myList new ListNodeString();myList.add(a);myList.add(b);myList.add(c);myList.add(d);myList.add(e);myList.add(f);System.out.println(第三个元素是: myList.get(3));myList.remove(3);System.out.println(删除之后第三个元素是:myList.get(3));System.out.println(-----------替换之后--------);myList.replace(1, b11);System.out.println(myList.get(1));}运行一下上述main函数我们随意写了几个测试方法控制台打印结果 大家可以看到代码中大量使用了递归来实现主要是想深入的使用一下递归同时使用递归来实现节省了较多的代码量而且比较容易理解单链表的实现到此结束谢谢观看