zoukankan      html  css  js  c++  java
  • 【手绘漫画】面试必考之手撕单链表(解题模板和深度剖析),(LeetCode 707)

    在这里插入图片描述

    图解算法与数据结构

    1、前言

    今天开始链表,这一讲是单链表,下一讲是双链表。

    下面一起来看看吧!!!
    在这里插入图片描述
    在这里插入图片描述

    2、代码

    模板:

    //C++单向链表模板
    class MyLinkedList{
    private:
    	struct ListNode{
    		int val;
    		ListNode *next;
    		ListNode(int x) :val(x), next(nullptr){}
    	};
    	ListNode* head;
    public:
    	MyLinkedList() :head(nullptr){}
    
    	//获得链表中第index个节点的值
    	int get(int index){
    		int i = 0;
    		ListNode *p = head;
    		while (p&&i<index){
    			p = p->next;
    			i++;
    		}
    		if (p)return p->val;
    		else return -1;
    	}
    
    	//在链表头部插一个值为val的节点
    	void addAtHead(int val){
    		ListNode *p = new ListNode(val);
    		p->next = head;
    		head = p;//更换头节点
    	}
    
    	//在链表尾部添加一个值为val的节点
    	void addAtTail(int val){
    		ListNode *p = new ListNode(val);
    		//链表为空,直接将新节点作为头节点
    		if (head == nullptr){
    			head = p;
    			return;
    		}
    		ListNode *q = head;
    		//遍历直到q的next节点为空
    		while (q->next){
    			q = q->next;
    		}
    		q->next = p;
    	}
    
    	//在索引为index的节点之前添加值为val的节点
    	void addAtIndex(int index, int val){
    		ListNode *node = new ListNode(val);
    		//1、index小于等于0,直接在头部插入节点
    		if (index <= 0){
    		//若index小于等于0,我们仅需要在头节点前面插入新节点就行了
    			//注意这里不能使用指针p,因为p=node时,p所指向的地址发生了变化,head指向的地址没有变化,所以我们这里要使用指针head
    			node->next = head;
    			head = node;
    			return;
    		}
    		int i = 0;
    		ListNode *p = head;
    		//在索引为index的节点之前插入新节点,我们需要找到它的前驱节点,然后插入在它的前驱节点后面
    		while (p&&i<index - 1){
    			p = p->next;
    			++i;
    		}
    		//2、p为索引节点的前驱节点
    		if (p){
    			node->next = p->next;
    			p->next = node;
    		}
    	}
    
    	//删除索引为index的节点
    	void deleteAtIndex(int index){
    		//1、index为0,我们直接删除head节点
    		if (index == 0 && head != nullptr){
    			ListNode *del = head;
    			head = head->next;
    			delete del;
    			return;
    		}
    		int i = 0;
    		ListNode* p = head;
    		//删除索引为index的节点,我们需要找到它的前驱节点p,p->next为需要删除节点
    		while (p&&i<index - 1){
    			p = p->next;
    			i++;
    		}
    		//2、index超过链表范围,删除失败
    		if (!p)return;
    		//3、index的位置合法,我们找到需要删除的p->next节点
    		if (p->next){
    			ListNode *del = p->next;
    			p->next = del->next;
    			delete del;
    		}
    	}
    
    	int length(){
    		int i = 0;
    		ListNode *p = head;
    		while (p){
    			i++;
    			p = p->next;
    		}
    		return i;
    	}
    };
    

    在这里插入图片描述

    3、正文

    单链表中的每个结点不仅包含值,还包含链接到下一个结点的引用字段。通过这种方式,单链表将所有结点按顺序组织起来。

    首先初始化你的单链表:
    在这里插入图片描述
    val 是值,next 是指针。

    如果想在给定的结点之后添加新值,分三种情况:

    • 头结点;
      在这里插入图片描述
    • 尾结点;
      在这里插入图片描述
    • 任意位置;
      在这里插入图片描述

    与数组不同,不需要将所有元素移动到插入元素之后。因此,可以在 O(1) 时间复杂度中将新结点插入到链表中,这非常高效。

    如果想从单链表中删除现有结点,分两种情况:

    • 头结点;
      在这里插入图片描述
    • 任意位置;
      在这里插入图片描述

    删除结点的时间复杂度将是 O(N)。空间复杂度为 O(1),因为只需要常量空间来存储指针。
    在这里插入图片描述

    4、实例

    LeetCode 707,一个设计链表的题。
    在这里插入图片描述
    在这里插入图片描述
    代码如上。

    /**
     * Your MyLinkedList object will be instantiated and called as such:
     * MyLinkedList* obj = new MyLinkedList();
     * int param_1 = obj->get(index);
     * obj->addAtHead(val);
     * obj->addAtTail(val);
     * obj->addAtIndex(index,val);
     * obj->deleteAtIndex(index);
     */
    

    在这里插入图片描述
    在这里插入图片描述

    如果有幸帮到你,请帮我点个【赞】,给个【关注】!如果能顺带【评论】给个鼓励,我将不胜感激。

    如果想要更多的资源,欢迎关注 @我是管小亮,文字强迫症MAX~

  • 相关阅读:
    C语言课程设计 学生信息管理系统 (简单版)
    Windows 常用Cmd命令行 (持续更新...)
    C++课程设计 通讯录管理系统 原码及解析
    C++ Error 个人笔记(live)
    sql查询当天数据
    web.xml中load-on-startup标签的含义
    @Repository、@Service、@Controller 和 @Component
    SQL Server JDBC驱动中sqljdbc和sqljdbc4区别
    windows下设置/删除Tomcat的开机自启动
    【Python技巧系列】条件语句一行实现
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13302570.html
Copyright © 2011-2022 走看看