算法篇一【线性表】:链表及经典问题(一)之链表的基础知识和构造链表

链表(List)及经典问题

一、链表的基础知识:
单向链表
什么是链表结构?
若干个节点,串成一条链的结构,每个节点都有两个区域,一个是数据域,一个是指针域
地址可以唯一的标识一个对象(数组下标(门牌号)是一个特殊地址,数组下标是相对地址的概念)
树是树,链表是链表,链表添加一个指针,就是单项链表增加一个指针域。
本质上树和链表差多了。
单向链表只有一个指针,只能王一个方向走;双向是两个指针,可以两边走。
头节点是否存储数据,根据设计程序的需要决定。
特点:
1、链表中的每个节点至少包含两个部分:数据域和指针域
2、链表中的每个节点,通过指针域的值,形成一个线性结构
3、查找节点O(n),插入节点O(1),删除节点O(1)
4、不适合快速的定位数据,适合动态的插入和删除数据的应用场景

手动构造链表:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <stack>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <vector>
using namespace std;

//链表是一种思维逻辑结构:
//struct 相当于javascript中的class
//C语言中的指针可以理解为java中的引用

struct Node {
    Node(int data): data(data),next(NULL){}
    int data; //链表的数据域
    Node *next;//指针域
};

//完全反转链表
void reverse(Node *p){
    if(p == NULL) return ;
    reverse(p->next);
    printf("%d->",p->data);
    return ;
}
//反转链表头n个节点
Node *reverse(Node *head, int n){
    if(n == 1) return head;
    Node *tail = head->next, *p = reverse(head->next, n - 1); //往下一层传的时候,反转n-1个节点
    head->next = tail->next;
    tail->next = head;
    return p;
}
int main() {
    Node *head = NULL; //链表的头
    head = new Node(1);
    head->next = new Node(2);//head指向下一个节点
    head->next->next = new Node(3);
    head->next->next->next = new Node(4);
     //至此,构造了一条包含4个节点的链表

    //完全反转链表:
    reverse(head);printf("\n");

    //反转链表的头3个节点
    head = reverse(head,3);

    Node *p = head;

    //当p不指向空节点的时候
    while(p != NULL){
        printf("%d->",p->data);
        p = p->next;
    }
    printf("\n");
    return 0;
}


运行结果
在这里插入图片描述

另一种链表的构建方法:

#include <iostream>

int data[10];
int next[10];
void add(int ind,int p,int val){
    //保证可以在中间插入:
    next[p] = next[ind];
    next[ind] = p;
    data[p] = val;
    return;
}
//构造一个链表,再访问链表
int main(){
    int head = 3;
    data[3] = 0;
    add(3,5,1);
    add(5,2,2);
    add(2,7,3);
    add(7,9,100);
    //中间插入:在5节点后面插入6节点的值是123
    add(5,6,123);
    // 访问链表
    int p = head;
    while(p != 0){
        printf("%d->",data[p]);
        p = next[p];
    }
    return 0;
}

运行结果:
在这里插入图片描述

链表的典型应用场景:
场景一:
操作系统内的动态内存分配:
一共3G内存,底层的分配是链表形式的指向
在这里插入图片描述

场景二:
LRU缓存淘汰算法:
什么是缓存?
对低速设备的一种有效管理手段(高速设备的一种称呼)
内存对CPU读取数据速度非常快,硬盘读取的非常慢,所以我们可以把CPU经常用到的数据存储到内存中
(下图:1GB就是内存-缓存;512GB是硬盘)
在这里插入图片描述

缓存内部的数据试如何维护的?
描述:链表的方式维护的。
涉及概念:
1、缓存大小:
2、缓存命中:
如果进来一个数据是1,命中该数据1,直接读取
在这里插入图片描述

如果进来一个数据5,没有命中,那么它就添加在链表尾,数据1被删除,这就是LRU缓存淘汰算法。
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值