代码随想录|链表基础知识

文章介绍了链表的基本概念,包括数据域和指针域,以及单链表、双链表和循环链表。强调链表与数组在存储方式和操作特性上的差异,如数组空间连续,链表空间随机分布。文中详细阐述了链表节点的添加、删除操作,并对比了直接操作和使用虚拟头节点两种方法。此外,还讨论了如何在链表中插入和删除节点,以及获取特定位置节点的值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一:基础知识(我感觉链表在形式表达上和指针相同,在内容表达上与数组相同)

二:操控节点的几种方式


记于2023-1-16  

一:基础知识(我感觉链表在形式表达上和指针相同,在内容表达上与数组相同)

                1.数据域  指针域(链接内存中的各个结点)

                2.单链表  双链表  循环链表

                3.与数组的存储方式不同,数组的内存空间是连续的分布,而链表的空间是由系统随机分布,除起始和终止节点是确定了。 

         数组的空间确定(数据量确定,若不确定就会重新定义新的数组)所以多查找 少增删  ,而链表的内存空间不是很确定(数据量不是固定的),所以多增删,少查询。

                4.链表节点的定义   

//单链表的定义
struct ListNode{
        int val;//节点上存储的元素
        ListNode *next;//指向下一个节点的指针
        ListNode(int x):val(x),next(NULL){}  //节点的构造函数
};
//通过自己定义构造函数的初始化节点
ListNode* head=new ListNode(5)
//默认构造函数初始化节点
ListNode* head = new ListNode();
head->val = 5;//指针的表示

                5.链表节点的删除和增添  删除节点在c/c++中要手动释放删除的内存空间,其他语言不用手动管理内存

1.删除节点:头节点:head=head->nest;

                     非头节点:cur->next=cur->next->next;

                     以上两种方式要学会判断并 使用if循环,或者直接使用虚拟节点,统一为有头节点的方式

删除的节点前后都不能为NULL(注意操作的节点不能为空指针)

2.插入节点 找到第n个节点设置为cur->next,注意新节点的设置顺序,先新节点->第n个节点,再使第n个节点的前一个节点为->新节点

代码见下


二:操控节点的几种方式

删除节点的两种方式

(1)直接使用原来的代码进行操作

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        while(head!=NULL &&  head->val)//删除头节点
        ListNode* temp=head;  //定义新的链表指针指向头节点
        head=head->next;//当满足此条件时,head移动到下一个
        delete temp;//删除头节点
    }
//删除非头节点
ListNode* cur=head;
while(cur!=NULL&&cur->next!=NULL)
{
    if(cur->next->val==val)
    {
        ListNode* temp=cur->next;
        cur->next=cur->next->next;
        delete temp;   
    }
    else cur=cur->next;
    //为下一次判断cur做准备,因为这里进行while循环,所以会遍历到最后一个节点
}
return head;//这里可以发现返回的是头节点 与数组的地址相似,head的值一直都没有改变
}
};
      

(2).设置一个虚拟头节点进行操作

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode* dummyHead = new ListNode(0);//设置一个虚拟节点
        dummyHead->next = head;//将虚拟头指向head,这样方便删除操作
        //注意这个是为什么要这样,若是换成head->next,就会导致最后不能正确的返回头节点
        ListNode* cur = dummyHead;
        while(cur->next!=NULL){
                if(cur->next->val == val){
                    ListNode* temp=cur->next;
                    cur->next=cur->next->next;
                    delete temp;
                    }else {
                        cur=cur->next;
                    //进行这样的操作是为了方便下一次的遍历循环
                    }
            }
        head=dummyHead->next;//这里需要注意重新定义head,前面的
        delete dummyHead;
        return head;
    }
};//还是要对虚拟节点进行理解为什么前面设置了dummyHead=head后,后面又要重新将head赋值
                    

获取链表中第 index 个节点的值。如果索引无效,则返回-1。//获取该节点的方式很特殊

cur=dummyHead->next;//参照上面设置新节点的方式
while(n)
{
cur=cur->next;
n--;
//此时节点的值应该是从n=0开始计算,应为此时n>=0&&n<=size-1;
//n最后为0,就是当前节点,停止循环
}
return cur->val;


在头部插入一个节点、

ListNode* newNode = new ListNode(val);
newNode->next = dummyHead->next;
dummyHead->next = newNode;/
/注意这两个式子的顺序,由于是头部插入节点所以
//要先将新链表指向head,再让dummyHead指向newNode
size++;

在尾部插入节点

LinkedNode* newNode = new LinkedNode(val);
//定义一个新节点
cur = dummyHead;
while(cur->next!=NULL)
{
   cur=cur->next;//b站的视频上的cur箭头不是表示链表指向
   cur->next=newNode;
}

第n个节点之前插入一个节点

cur要指向第n个节点之前的一个节点,在cur和cur->next(第n个节点)之间插入一个节点,所以寻找方法是和获取第n个节点的方式相同。

LinkedNode* newNode = new LinkedNode(val);
cur=dummyHead;
while(n){//保证第n个节点为cur->next
cur=cur->next;//找到两个节点 cur 和cur->next  
n--;
newNode->next=cur->next;
cur->next=newNode;
size++;
}

删除第n个节点(找到的第n个节点一定是cur->next)

cur=dummyHead;
//找到前一个节点  cur cur->next(第n个节点)
while(n)
{cur=cur->next;
n--;
}
cur-next=cur->next->next;//与删除节点方式相同
//适当语言delete
size--;

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值