精华内容
下载资源
问答
  • 双向链表和双向循环链表 介绍: (Introduction:) Before going into doubly linked list implementation, you must have basic knowledge about Linked List. If you haven’t read about Linked List or Singly ...

    双向链表和双向循环链表

    介绍: (Introduction:)

    Before going into doubly linked list implementation, you must have basic knowledge about Linked List. If you haven’t read about Linked List or Singly Linked List yet, click here to read.

    在进行双重链表实现之前,您必须具有有关链表的基本知识。 如果您尚未阅读链表或单链表请单击此处阅读。

    And if you are already aware about Singly Linked List, then you are at right place to proceed further.

    并且,如果您已经知道单链列表 ,那么您来对地方了。

    Doubly linked list is a collection of nodes. Node consists of three parts:

    双链表是节点的集合。 节点包括三个部分:

    1. Pointer to Previous Node

      指向上一个节点的指针
    2. Data

      数据
    3. Pointer to Next Node

      指向下一个节点的指针
    Image for post
    Pictorial representation of Doubly Linked List
    双链表的图形表示

    A Node and Doubly Linked list can be represented using below structure in Go:

    可以在Go中使用以下结构表示NodeDoubly Linked列表

    Node and Doubly linked list structure
    节点和双链表结构

    You will see the terms of Head and Tail throughout this story. So basically Head is the pointer that points to the first node of the list. What about Tail?

    在整个故事中,您将看到“ 尾”的用语。 因此,基本上, Head是指向列表第一个节点的指针。 尾巴呢?

    You guessed it right! Tail is the pointer that points to the last node of the list.

    您猜对了! 尾巴是指向列表的最后一个节点的指针。

    Now, I hope you have gone through the basics of the doubly linked list. So, without wasting time let’s jump into some of the operations that can be performed on Doubly linked list.

    现在,我希望您已经了解了双向链表的基础知识。 因此,在不浪费时间的情况下,让我们跳入可以在双链表上执行的一些操作。

    Note: In this tutorial, while performing operations using index/position, zero is considered as the first position

    注意:在本教程中,使用索引/位置执行操作时,零被视为第一个位置

    1.插入节点 (1. Inserting a node)

    1.1 Insert a node at the start of the list

    1.1在列表的开头插入一个节点

    Inserting a node at the beginning of the list is as easy as performing the below steps:

    将节点插入列表的开头与执行以下步骤一样容易:

    1. Create a node

      创建一个节点

    2. Assign value to the node

      为节点分配值

    3. Set the new node’s pointer to next node with existing Head pointer and pointer to prev node as NULL

      使用现有的Head指针和指向上一个节点的指针将新节点的指针设置为下一个节点为NULL

    4. Change the value of Head so that it will point to new node

      更改Head的值,使其将指向新节点

    Image for post
    Pictorial representation of inserting a node at the start of the list
    在列表的开头插入节点的图形表示

    Following code will simply demonstrate:

    以下代码将简单演示:

    Inserting a node at the start of the list
    在列表的开头插入一个节点

    1.2 Insert a node at the end of the list

    1.2在列表末尾插入一个节点

    In singly linked list, we have to traverse the complete list to add a node at the end of list. But, as doubly linked list introduces a new Tail pointer, no need to traverse the entire doubly linked list to add a node.

    在单链列表中,我们必须遍历完整列表以在列表末尾添加一个节点。 但是,由于双向链表引入了新的Tail指针,因此无需遍历整个双向链表即可添加节点。

    Following are the steps to add a node at the end of list:

    以下是在列表末尾添加节点的步骤:

    1. Create a node

      创建一个节点

    2. Assign value to the node

      为节点分配值

    3. Set the new node’s pointer to prev node with existing Tail pointer and pointer to next node as NULL

      使用现有的Tail指针和指向下一个节点的指针将新节点的指针设置为上一个节点为NULL

    4. Change the value of Tail so that it will point to new node

      更改Tail的值,使其将指向新节点

    Image for post
    Pictorial representation of inserting a node at the end of the list
    在列表末尾插入节点的图形表示

    Below code can be used to insert a node at the end of list:

    以下代码可用于在列表末尾插入节点:

    Inserting a node at the end of the list
    在列表末尾插入一个节点

    1.3 Insert a node at a particular position

    1.3在特定位置插入节点

    We’ve seen the process of inserting a node at the beginning and end of list. What about inserting a node elsewhere? like inserting node at a particular position. For this we need to follow below steps:

    我们已经看到了在列表的开头和结尾插入节点的过程。 如何在其他位置插入节点呢? 例如在特定位置插入节点。 为此,我们需要执行以下步骤:

    1. Create a node

      创建一个节点

    2. Assign value to the node

      为节点分配值

    3. Now get the existing node from provided position and set it’s pointer to prev node with new node

      现在从提供的位置获取现有节点并将其指针设置为具有新节点的上一个节点

    4. Set new node’s pointer to next node with existing node(that we got in step 3)

      将新节点的指针设置为具有现有节点的下一个节点(我们在步骤3中获得)

    5. Now get the node from provided position-1 location and set it’s pointer to next node with new node

      现在从提供的position-1位置获取节点,并将其指针设置为具有新节点的下一个节点

    6. Set pointer to prev node of new node with the position-1 location node(that we got in step 5)

      使用position-1位置节点(在步骤5中获得)设置指向新节点的上一个节点的指针

    Image for post
    Pictorial representation of inserting a node at a particular position
    在特定位置插入节点的图形表示

    Below code will explain the things more clearly:

    下面的代码将更清楚地解释这些内容:

    Inserting a node at a particular position
    在特定位置插入节点

    2.打印链接列表节点 (2. Printing linked list nodes)

    As we have already seen, doubly linked list can be traversed in two ways i.e. forward traversal and backward traversal.

    正如我们已经看到的,可以通过两种方式遍历双向链表,即向前遍历和向后遍历。

    Forward traversing can be done using Head pointer that points to the first node then visiting next nodes using pointer to the next node & so on until we reach the pointer to next node as NULL.

    可以使用Head指针进行前向遍历,该Head指针指向第一个节点,然后使用指向下一个节点的指针访问下一个节点,依此类推,直到我们到达指向下一个节点的指针为NULL为止。

    Let’s understand it using below code:

    让我们用下面的代码来理解它:

    Printing linked list nodes in forward direction
    向前打印链接列表节点

    Whereas, backward traversing can be done using Tail pointer that points to the previous node then visiting previous nodes using pointer to prev node & so on until we reach pointer to prev node as NULL.

    而使用向后节点的Tail指针可以进行​​向后遍历,然后使用指向prev node的指针访问先前的节点,依此类推,直到到达指向prev node的指针为NULL为止。

    You can see the below code to understand:

    您可以查看以下代码来了解:

    Printing linked list nodes in backward direction
    向后打印链接列表节点

    3.搜索节点 (3. Searching a node)

    Search operation can also be performed using two ways: searching a node using Head pointer (forward traversal) or searching a node using Tail pointer(backward traversal). But in below code we are using the forward traversal.

    搜索操作也可以通过两种方式执行:使用Head指针搜索节点(向前遍历)或使用Tail指针搜索节点(向后遍历)。 但是在下面的代码中,我们使用正向遍历。

    Searching a node using value
    使用值搜索节点

    As we’ve seen getting a node’s position by it’s value, What about getting a node from a particular position?

    正如我们所看到的,通过它的值获得节点的位置,如何从特定位置获得节点呢?

    Following code will help you to get that.

    以下代码将帮助您实现这一目标。

    Get a node from a particular position
    从特定位置获取节点

    4.删除节点 (4. Deleting a node)

    4.1 Delete first node from list

    4.1从列表中删除第一个节点

    Deleting a node from the beginning of list is much easier, just follow couple of steps and you are done.

    从列表的开头删除节点要容易得多,只需执行以下几个步骤即可。

    1. Change the existing Head pointer with Head’s pointer to next node

      使用Head的指针将现有的Head指针更改为下一个节点

    2. Set the Head’s pointer to previous node as NULL

      将Head的指向上一个节点的指针设置为NULL

    That’s it 😃

    就是这样

    Image for post
    Pictorial representation of deleting first node from list
    从列表中删除第一个节点的图形表示

    Let’s see the code:

    让我们看一下代码:

    Deleting first node from list
    从列表中删除第一个节点

    4.2 Delete last node from list

    4.2从列表中删除最后一个节点

    Deleting a last node of list is similar and as easy as deleting the first node. Difference is that, here we are changing the Tail value instead of Head.

    删除列表的最后一个节点与删除第一个节点一样简单。 不同之处在于,这里我们更改的是Tail值而不是Head。

    1. Change the existing Tail pointer with Tail’s pointer to previous node

      使用Tail的指针将现有的Tail指针更改为上一个节点

    2. Set the Tail’s pointer to next node as NULL

      将Tail的指向下一个节点的指针设置为NULL

    Image for post
    Pictorial representation of deleting last node from list
    从列表中删除最后一个节点的图形表示

    Below code implements the above given steps:

    下面的代码实现了上述步骤:

    Deleting last node from list
    从列表中删除最后一个节点

    4.3 Delete a node from particular position

    4.3从特定位置删除节点

    Deleting a node at a given position needs some extra steps over deleting at first and last node. Because, as you can see in below image, here we are changing the links of previous and next node. Let’s see the required steps:

    与在第一个节点和最后一个节点删除相比,在给定位置删除节点需要一些额外的步骤。 因为,如您在下图所看到的,在这里我们正在更改上一个节点和下一个节点的链接。 让我们看看所需的步骤:

    1. If position points to first node we are using the Delete first node flow and if it points to last node we are using Delete last node flow.

      如果位置指向第一个节点,则使用“删除第一个节点”流;如果位置指向最后一个节点,则使用“删除最后一个节点”流。

    2. Otherwise, get the existing node from given position

      否则,从给定位置获取现有节点

    3. Change the next node’s pointer to prev node with the node’s pointer to prev node

      下一个节点的指针更改为 上一个 节点与节点的指针指向 上一个 节点

    4. Change the previous node’s pointer to next node with the node’s pointer to next node

      前一节点的指针更改为 下一个 节点与节点的指针指向 下一个 节点

    Confused? below picture will clear the things.

    困惑? 下面的图片将清除一切。

    Image for post
    Pictorial representation of deleting a node from particular position
    从特定位置删除节点的图形表示

    Let’s see the code to delete a node using it’s position:

    让我们看一下使用其位置删除节点的代码:

    Deleting a node from particular position
    从特定位置删除节点

    You can find the complete code here.

    您可以在此处找到完整的代码。

    Let’s see the advantages and disadvantages of doubly linked list over singly linked list

    让我们看看双链表相对于单链表的优缺点

    Advantages:1. We can traverse a Doubly linked list in both ways i.e. in forward and backward direction2. Insert and delete operations are more easy if previous pointer is known

    优点: 1.我们可以通过两种方式遍历双链表,即向前和向后2。 如果先前的指针已知,则插入和删除操作会更容易

    Disadvantages:1. Requires extra memory space for pointer to previous node as compared to singly linked list2. Extra operation of maintaining pointer to previous node needs to be performed while insertion and deletion

    缺点: 1.与单链接list2相比,需要额外的存储空间来指向前一个节点。 在插入和删除时,需要执行维护指向先前节点的指针的额外操作

    Some of the applications of Doubly Linked List:

    双链表的一些应用:

    1. Music player with previous and next buttons

      具有上一个和下一个按钮的音乐播放器
    Image for post
    Music player’s previous and next buttons
    音乐播放器的上一个和下一个按钮

    2. Web browser’s cache with backward and forward buttons

    2. Web浏览器的缓存,带有后退和前进按钮

    Image for post
    Web browser’s backward and forward buttons
    Web浏览器的后退和前进按钮

    3. Undo and redo functionality

    3.撤消和重做功能

    Image for post
    Undo and redo buttons
    撤消和重做按钮

    4. Text Editor

    4.文字编辑器

    Image for post
    Text editor’s insertion point
    文字编辑器的插入点

    As you can see in above image, the insertion point is after character “l”. so when we need to add character after it like “-” it means we are adding a node into doubly linked list. It’s pointer to previous node points to character “l” and pointer to next node points to character “c”. And the final linked list becomes “Wel-come”. As you move the insertion point forward or backward, it means you are traversing the list.

    如上图所示,插入点位于字符“ l”之后。 因此,当我们需要在字符后添加“-”之类的字符时,表示我们正在将节点添加到双向链表中。 它指向上一个节点的指针指向字符“ l”,指向下一个节点的指针指向字符“ c”。 最后的链接列表变为“欢迎使用”。 在向前或向后移动插入点时,这意味着您正在遍历列表。

    结论: (Conclusion:)

    In this story, we’ve seen some basics of doubly linked list like:

    在这个故事中,我们已经看到了双向链表的一些基础知识,例如:

    • Doubly linked lists can be traversed in forward and backward direction

      双向链表可以向前遍历 向后 方向

    • An extra pointer to previous node is used in doubly linked list over singly linked list which helps in backward traversal

      在单链表上的双链表中使用了指向上节点的额外指针,这有助于向后遍历

    • Doubly linked list operations like insertion, deletion, searching & traversal

      双链列表操作,如插入删除搜索 遍历

    • We’ve seen the advantages & disadvantages doubly linked list over singly linked list

      我们已经看到了优势 缺点 单链表上的双链表

    • Some applications of real world examples like Media player’s Next & Previous operations, Web browser’s cache with backward and forward operations where doubly linked lists are used.

      真实示例的某些应用程序,例如媒体播放器的“下一个” 和“ 上一个”操作,具有向后和向前操作的Web浏览器缓存 ,其中使用了双向链接列表。

    That’s it from my side. Any suggestions & corrections are highly welcomed.

    就我而言就是这样。 任何建议和更正均受到高度欢迎。

    Stay happy 😊 & keep reading.

    保持快乐😊并继续阅读。

    翻译自: https://medium.com/@pawar.ritesh4u/how-to-deal-with-doubly-linked-list-in-simple-ways-4d68a78b1d9b

    双向链表和双向循环链表

    展开全文
  • 双向循环链表介绍 双向循环链表和单向循环链表最大的区别就是可以通过当前结点找到下一个结点和上一个结点,比如说对链表进行删除操作,单向链表通过当前节点是找不到上一个节点的,因此不能删除传入的节点,只能...

    双向循环链表介绍

    双向循环链表和单向循环链表最大的区别就是可以通过当前结点找到下一个结点和上一个结点,比如说对链表进行删除操作,单向链表通过当前节点是找不到上一个节点的,因此不能删除传入的节点,只能删除传入的节点的下一个结点。单向链表如果真想删除传入的节点,可以让下一个结点的值等于传入的结点,让传入结点的下一个结点等于下下一个结点。代码实现

    //单向链表删除传入结点
    public void remove(Node node){
     //拿到传入结点的下一个结点的值
     int value = node.next.value;
     //让传入结点的值等于刚拿到的下一个结点的值
     node.value = value;
     //让传入结点的下一个结点等于下下个结点
     node.next = node.next.next;
    }
    
    
    //如果是双向链表,移除传入结点
    public void remove(Node node){
    //找到传入结点的下一个结点
    Node next = node.next;
    //传入结点的上一个结点的下一个结点等于传入结点的下一个结点
    node.pre.next = node.next;
    }
    
    

    代码实现双向循环链表:

    public class DoubleNode {
        private DoubleNode pre = this;
        private DoubleNode next = this;
        private int data;
    
        public DoubleNode(int data){
            this.data = data;
        }
    
        //添加节点
        //只需要让当前结点和新节点产生关系,点前结点的下一个结点和新节点产生关系即可。
        public void after(DoubleNode node){
            //先找到当前节点的下一个节点
            DoubleNode next = this.next;
    
            //当前节点的下一个节点是新节点
            this.next = node;
    
            //新节点的上一个节点是当前节点
            node.pre = this;
    
            //新节点的下一个结点是当前结点的下一个结点
            node.next = next;
    
            //当前结点的下一个节点的上一个结点是新节点
            next.pre = node;
        }
        
        //获取下一个结点
        public DoubleNode getNext(){
            return this.next;
        }
        
        //获取上一个结点
        public DoubleNode getPre(){
            return this.pre;
        }
        
    }
    

    双向链表图形结构:
    image.png

    展开全文
  • 单向循环链表介绍 它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环,如图所示: 从图中可以看出它和单链表唯一区别就是没有最后一个结点了。假设只有一个结点他的下一个结点就是其本身,因此...

    单向循环链表介绍

    它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环,如图所示:
    image.png
    从图中可以看出它和单链表唯一区别就是没有最后一个结点了。假设只有一个结点他的下一个结点就是其本身,因此构建一个循环单链表也非常简单,只需要把单链表的下一个结点换成当前结点。

    public class Node<T> {
        private T value;
        private Node next = this;
    
        public Node(T value) {
            this.value = value;
        }
    
        //添加元素
        //如果只有一个结点当前结点的下一个结点就是本身。
        //如果进行插入的话,当前结点的下一个结点是新插入的节点,新插入的节 
          点的下一个节点是刚才记录的下一个结点
        public Node append(Node node) {
            //记录下一个结点
           Node n = next;
           //当前结点的下一个结点等于新节点
           this.next = node;
           //新节点的下一个指向当前结点
           node.next = n;
           
        }
    
        //删除结点
        //单向链表,是不能删除自己,只能删除自己后边的结点
        public void dele(Node node) {
            //找到传入结点的下下个结点
            Node next = node.next.next;
            node.next = next;
        }
       
    }
    
    展开全文
  • 数据结构:单向循环链表(2)

    千次阅读 2020-07-04 16:04:22
    单向循环链表引子查询修改MyList测试测试1,没有节点测试2,有节点,但没有对应的节点测试3,有节点,有对应的节点删除(续)修改MyList测试测试1,没有节点测试2,有节点,但没有对应节点测试3,有一个节点,有对应...

    引子

    承接我的上一篇博客传送门

    查询

    同样的,链表不适合查询以及修改操作,不过我们是练习,简单的实现以下

    修改MyList

    public Node queryNodeByValue(int value)
    	{
    		if(this.size == 0L) return null;//如果没有节点直接返回
    		Node currNode = this.firstNode;
    		long flag = 0L;//判断链表是否已经完整遍历,防止死循环
    		while(currNode.getValue() != value)
    		{
    			flag++;
    			if(flag >= this.size) break;//已经遍历过一遍,跳出循环
    			currNode = currNode.getNextNode();
    		}
    		//判断是因为已经遍历过一遍而退出循环
    		//还是因为找到了对应节点退出循环
    		if(currNode.getValue() == value) return currNode;
    		else return null;
    	}
    

    测试

    测试1,没有节点

    @Test
    	void testDeleteLastNode() {
    		MyList myList = new MyList();
    		System.out.println(myList.deleteLastNode());
    	}
    

    结果
    在这里插入图片描述

    测试2,有节点,但没有对应的节点

    @Test
    	void testQueryNodeByValue2() {
    		MyList myList = new MyList();
    		Node node1 = new MyList.Node(1);
    		myList.setFirstNode(node1);
    		Node currNode = myList.queryNodeByValue(2);
    		System.out.println(currNode);
    	}
    

    结果
    在这里插入图片描述

    测试3,有节点,有对应的节点

    @Test
    	void testQueryNodeByValue3() {
    		MyList myList = new MyList();
    		Node node1 = new MyList.Node(1);
    		myList.setFirstNode(node1);
    		Node currNode = myList.queryNodeByValue(1);
    		System.out.println(currNode);
    		System.out.println(currNode.getNextNode());
    		System.out.println(currNode.getPreNode());
    	}
    

    结果
    在这里插入图片描述

    删除(续)

    我的上一篇博客,已经写了删除第一个节点跟最后一个节点,既然写了按值查询节点,那理应加上按值删除

    修改MyList

    public String deleteNodeByValue(int value)
    	{
    		Node currNode = queryNodeByValue(value);
    		//没有对应节点,直接返回
    		if(currNode == null) return "没有值为"+value+"的节点,删除失败";
    		Node preNode = currNode.getPreNode();//被删除节点的上一个节点
    		Node nextNode = currNode.getNextNode();//被删除节点的下一个节点
    		//如果只有一个节点,firstNode直接置空,大小减一即可
    		if(currNode == this.firstNode && this.size == 1L)
    		{
    			this.firstNode = null;
    			this.size--;
    			return "删除成功";
    		}
    		//如果删除的是第一个节点,而且有两个以上节点
    		//首先应该更改firstNode指向
    		if(currNode == this.firstNode && this.size > 1L)
    		{
    			this.firstNode = nextNode;
    		}
    		preNode.setNextNode(nextNode);
    		nextNode.setPreNode(preNode);
    		this.size--;
    		return "删除成功";
    	}
    

    测试

    测试1,没有节点

    @Test
    	void testDeleteNodeByValue() {
    		MyList myList = new MyList();
    		System.out.println("---删除前---");
    		System.out.println(myList);
    		System.out.println(myList.queryAll());
    		System.out.println(myList.deleteNodeByValue(1));
    		System.out.println("---删除后---");
    		System.out.println(myList);
    		System.out.println(myList.queryAll());
    	}
    

    结果
    在这里插入图片描述

    测试2,有节点,但没有对应节点

    @Test
    	void testDeleteNodeByValue1() {
    		MyList myList = new MyList();
    		Node node1 = new MyList.Node(1);
    		myList.setFirstNode(node1);
    		System.out.println("---删除前---");
    		System.out.println(myList);
    		System.out.println(myList.queryAll());
    		System.out.println(myList.deleteNodeByValue(2));
    		System.out.println("---删除后---");
    		System.out.println(myList);
    		System.out.println(myList.queryAll());
    	}
    

    结果
    在这里插入图片描述

    测试3,有一个节点,有对应节点

    @Test
    	void testDeleteNodeByValue2() {
    		MyList myList = new MyList();
    		Node node1 = new MyList.Node(1);
    		myList.setFirstNode(node1);
    		System.out.println("---删除前---");
    		System.out.println(myList);
    		System.out.println(myList.queryAll());
    		System.out.println(myList.deleteNodeByValue(1));
    		System.out.println("---删除后---");
    		System.out.println(myList);
    		System.out.println(myList.queryAll());
    	}
    

    结果
    在这里插入图片描述

    测试4,有两个节点,对应节点为首节点

    @Test
    	void testDeleteNodeByValue3() {
    		MyList myList = new MyList();
    		Node node1 = new MyList.Node(1);
    		Node node2 = new MyList.Node(2);
    		myList.setFirstNode(node1);
    		myList.addNode(node2);
    		System.out.println("---删除前---");
    		System.out.println(myList);
    		System.out.println(myList.queryAll());
    		System.out.println(myList.deleteNodeByValue(1));
    		System.out.println("---删除后---");
    		System.out.println("首节点的后继节点"+myList.getFirstNode().getNextNode());
    		System.out.println("首节点的前驱结点"+myList.getFirstNode().getPreNode());
    		System.out.println(myList);
    		System.out.println(myList.queryAll());
    	}
    

    结果
    在这里插入图片描述

    测试4,有两个节点,对应节点不是首节点

    @Test
    	void testDeleteNodeByValue4() {
    		MyList myList = new MyList();
    		Node node1 = new MyList.Node(1);
    		Node node2 = new MyList.Node(2);
    		myList.setFirstNode(node1);
    		myList.addNode(node2);
    		System.out.println("---删除前---");
    		System.out.println(myList);
    		System.out.println(myList.queryAll());
    		System.out.println(myList.deleteNodeByValue(2));
    		System.out.println("---删除后---");
    		System.out.println("首节点的后继节点"+myList.getFirstNode().getNextNode());
    		System.out.println("首节点的前驱结点"+myList.getFirstNode().getPreNode());
    		System.out.println(myList);
    		System.out.println(myList.queryAll());
    	}
    

    结果
    在这里插入图片描述

    测试5,有三个节点,对应节点为首节点

    @Test
    	void testDeleteNodeByValue5() {
    		MyList myList = new MyList();
    		Node node1 = new MyList.Node(1);
    		Node node2 = new MyList.Node(2);
    		Node node3 = new MyList.Node(3);
    		myList.setFirstNode(node1);
    		myList.addNode(node2);
    		myList.addNode(node3);
    		System.out.println("---删除前---");
    		System.out.println(myList);
    		System.out.println(myList.queryAll());
    		System.out.println(myList.deleteNodeByValue(1));
    		System.out.println("---删除后---");
    		System.out.println("首节点的后继节点"+myList.getFirstNode().getNextNode());
    		System.out.println("首节点的前驱结点"+myList.getFirstNode().getPreNode());
    		System.out.println(myList);
    		System.out.println(myList.queryAll());
    	}
    

    结果
    在这里插入图片描述

    测试6,有三个节点,对应节点不是首节点

    @Test
    	void testDeleteNodeByValue6() {
    		MyList myList = new MyList();
    		Node node1 = new MyList.Node(1);
    		Node node2 = new MyList.Node(2);
    		Node node3 = new MyList.Node(3);
    		myList.setFirstNode(node1);
    		myList.addNode(node2);
    		myList.addNode(node3);
    		System.out.println("---删除前---");
    		System.out.println(myList);
    		System.out.println(myList.queryAll());
    		System.out.println(myList.deleteNodeByValue(2));
    		System.out.println("---删除后---");
    		System.out.println("首节点的后继节点"+myList.getFirstNode().getNextNode());
    		System.out.println("首节点的前驱结点"+myList.getFirstNode().getPreNode());
    		System.out.println(myList);
    		System.out.println(myList.queryAll());
    	}
    

    结果
    在这里插入图片描述

    修改

    修改MyList

    	public String updateNodeByValue(int origin, int target)
    	{
    		Node currNode = queryNodeByValue(origin);
    		if(currNode == null) return "没有值为"+origin+"的节点,修改失败";
    		else  currNode.setValue(target);
    		return "修改成功";
    	}
    

    测试

    测试1,没有节点

    @Test
    	void testUpdateNodeByValue() {
    		MyList myList = new MyList();
    		System.out.println(myList.updateNodeByValue(1, 2));
    	}
    

    结果
    在这里插入图片描述

    测试2,有节点,没有对应节点

    @Test
    	void testUpdateNodeByValue1() {
    		MyList myList = new MyList();
    		Node node1 = new MyList.Node(1);
    		myList.addNode(node1);
    		System.out.println(myList.updateNodeByValue(2, 3));
    	}
    

    结果
    在这里插入图片描述

    测试3,有节点,有对应节点

    @Test
    	void testUpdateNodeByValue2() {
    		MyList myList = new MyList();
    		Node node1 = new MyList.Node(1);
    		myList.addNode(node1);
    		System.out.println("---修改前---");
    		System.out.println(myList);
    		System.out.println(myList.queryAll());
    		System.out.println(myList.updateNodeByValue(1, 3));
    		System.out.println("---修改后---");
    		System.out.println(myList);
    		System.out.println(myList.queryAll());
    	}
    

    结果
    在这里插入图片描述

    源码

    传送门

    展开全文
  • VUE基础篇(循环) 1、v-for v-for 是vue标签中指定for循环的标签,标签对应的值的也就是类似python中for循环或者java中foreach的写法 在vue中遍历可以分为三个部分: 1)遍历数组 2)遍历对象 3)数字迭代 1.1 遍历...
  • 基本概念和链表思想 链表的基本概念和结构 链表从js中的表现形式来看,其实就是一个具有一个属性用于存储数据,有一个属性用于存储下一个节点地址引用的对象结构,简易链表结构如下: function LinkNode(val, ...
  • Vue面试题

    2021-04-23 20:42:45
    Vue面试题 1.前端路由原理?两种实现方式有什么区别? 前端路由本质就是监听 URL 的变化,然后匹配路由规则,显示相应的页面,并且无须刷新页面。目前前端使用的路由就只有两种实现方式:Hash 模式和History 模式。 ...
  • 链表数据结构

    2020-02-27 13:24:37
    认识链表 我们先来认识一下链表, 看一下它大概的机制和原理, 以及和数组的对比. 链表和数组 数组: 要存储多个元素,数组(或列表)可能是最常用的数据结构。 我们之前说过, 几乎每一种编程语言都有默认实现...
  • Vue的芝士

    2021-07-27 11:16:05
    Vue JS Vue介绍 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或...
  • vue基础知识总结

    2020-11-20 15:31:34
    一、vue为什么要区分动态绑定class和style: :class是为了在当前页面(当前组件)中给某一个元素进行样式的动态切换 :style大部分在公共组件中书写,是方便进行子组件复用时候每个不同页面同一元素的样式改变。 ...
  • 双向链表数据结构

    2020-02-27 15:20:50
    认识双向链表 双向链表介绍 单向链表: 只能从头遍历到尾或者从尾遍历到头(一般从头到尾) 也就是链表相连的过程是单向的. 实现的原理是上一个链表中有一个指向下一个的引用. 单向链表有一个比较明显的缺点...
  • vue循环需加 :key=“唯一标识” ,唯一标识可以使item里面id index 等,因为vue组件高度复用增加key可以标识组件的唯一性,为了更好地区别各个组件key的作用主要是为了高效的更新虚拟DOM 原理: key的作用主要是...
  • vue3框架中就有大量的链表数据结构应用,学习链表对阅读源码有很大帮助。 数组应用场景:数据比较少;经常做的运算是按序号访问数据元素;数组更容易实现,任何高级语言都支持;构建的线性表较稳定。 链表应用场...
  • 一、Vue和 React设计思路 1、vue 1.1 vue1.x 只有响应式通知。 1.2 vue2.x 在vue1.x中如果项目很大的时候,响应...vue2.x中vdom同级比较复杂数组结构时使用双端预判的算法,减少循环diff的次数。 vue2.x中的静态标记只
  • 关于vue的阅读与总结,这是一份深入思考后的关于vue的理解。触类旁通,多多学习。 背景(为什么要学习开源项目的源码) 举一个最近自己看到的例子: vue-router插件中,借用vue.min可以混入生命周期,在这里混入的...
  • 数组与链表的区别

    2020-07-20 10:05:10
    链表: 1、链表是一系列的存储数据元素的单元通过指针串接起来形成的,因此每个单元至少有两个域,一个域用于数据元素的存储,另一个或两个域是指向其他单元的指针。这里具有一个数据域和多个指针域的存储单元...
  • 这是一个强大的简化,如果你曾研究过Vue代码库的复杂性,那么你就会知道这实际上不是事实。但是从根本上讲,这就是Vue为我们所做的事情。看一下这个组件:{{title}}SomewordsthatdescribethisthingClickityclick!...
  • VUE学习系列笔记day01

    2020-12-16 23:04:00
      1、vue可以当做库使用(引入js,可调用api),也可以当做框架使用。其是一个渐进式框架,渐进层次为:声明式渲染–组件系统–客户端路由–集中式状态管理–项目构建   2、{{}}为插值表达式,可将数据填充到...
  • 本篇主要有三部分 什么是链表 链表的实现 链表的变种 ...另外,今天2019年2月18日上午发现 2048-vue 版,代码版本不对,...链表存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的。每个 元素...
  • Vue Composition API React Hooks vs Vue Composition API 总结 场景 先理解什么是hook,拿react的介绍来看,它的定义是: 它可以让你在不编写 class 的情况下,让你在函数组件里“钩入” React...
  •  parent不是为undefined,并且标记位非抽象,通过while循环父组件链,找出第一个非抽象的组件,并赋值为parent,该parent的子组件数据添加vm对象,形成一个环形链表。 我们继续看剩余的代码: vm.$parent =...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,400
精华内容 560
关键字:

vue循环列表点击事件

vue 订阅