当前位置: 首页 > article >正文

单向链表与双向链表

当使用单向链表查看链表中某个节点的数据,可以使用快慢指针法

快慢指针:

快慢指针是一种在链表和数组中常用的算法技巧,主要用于解决链表或数组中的问题,如检测环

存在、找到环的入口、计算链表的中点等。快慢指针的核心思想是使用两个指针以不同的速度遍

链表或数组:

>慢指针(Slow Pointer):每次移动一步。

>快指针(Fast Pointer):每次移动两步。

使用场景

检测链表是否有环
  1. 如果快指针最终追上慢指针,说明链表中有环。

  2. 如果快指针到达链表的末尾,说明链表中没有环。

bool HasCircle(Node *head)
{
  if(head == NULL)
    return false;
  Node *slow = head, *fast = head;
  while(fast != NULL && fast->next!=NULL)
  {
     slow = slow->next; //慢指针每次前进一步
     fast = fast->next->next;//快指针每次前进两步
     if(slow == fast) //相遇,存在环
         return true;
  }
  return false;
}
输出链表中的倒数第K个节点(即正数第K-1个节点)
Link_node_t * find_k_link(Link_t *plink,int key)
{
    Link_node_t *pfast = find_link(plink,key);
    if(NULL == pfast)
    {
        return NULL;
    }
    pfast = pfast->pnext;
    Link_node_t *pslow = plink->phead;
    while(pfast != NULL)
    {
        pfast = pfast->pnext;
        pslow = pslow->pnext;
    }
    return pslow;
}

单向链表倒置

int inver_link(Link_t *plink)
{
    int len = link_lenth(plink);
    if(len == 0)
    {
        return -1;
    }
    Link_node_t *ptemp = plink->phead;
    plink->phead = NULL;
    Link_node_t *pinsert = NULL;

    while(ptemp != NULL)
    {
        pinsert = ptemp;
        ptemp = ptemp->pnext;
        pinsert->pnext = plink->phead;
        plink->phead = pinsert;
    }

    return 0;
}

单向链表排序(插入法)

将待插入的数,插入到一个有序的序列中,使得到的序列仍然有序

void insert_sort(Link_t *plink)
{
    Link_node_t *ptemp = plink->phead->pnext;
    plink->phead->pnext = NULL;
    while(ptemp != NULL)
    {
        Link_node_t *pinsert = ptemp;
        ptemp = ptemp->pnext;
        Link_node_t *p = NULL;
        if(plink->phead->data > pinsert->data)
        {
            pinsert->pnext = plink->phead;
            plink->phead = pinsert;
        }
        else
        {
            p = plink->phead;
            while(p->pnext != NULL && p->pnext->data < pinsert->data)
            {
                p = p->pnext;
            }
            pinsert->pnext = p->pnext;
            p->pnext = pinsert;
        }
    }
}

valgrind

在使用和操作链表时,需注意内存泄漏的情况,可以使用Valgrind来检查内存泄漏的情况

Valgrind 是一个编程工具,主要用于内存调试、内存泄漏检测、以及性能分析。

使用场景

>内存泄漏检测:检查程序是否在不再需要时未能释放分配的内存。

>内存越界:检测数组越界、堆栈缓冲区溢出等错误。

>线程错误:检查多线程程序中的同步问题,如死锁、竞争条件等。

>性能分析:分析程序的性能瓶颈,如CPU周期使用、内存访问模式等。

安装valgrind

sudo apt-get update
sudo apt-get install valgrind

运行valgrind

valgrind [选项] 程序名 [程序参数]

使用示例:


双向链表

双向链表与单向链表的区别:

单向链表只有一个后继指针

对于单向链表的某一个节点,只能找到其后的节点,而不能找到之前的节点

基础操作

头插
int push_doulink_head(Dlink_t *plink,DataType data)
{
    Dlink_node_t *pdouble = malloc(sizeof(Dlink_node_t));
    if(NULL == pdouble)
    {
        return -1;
    }

    pdouble->data = data;
    pdouble->pnext = NULL;
    pdouble->ppre = NULL;

    if(is_empty_link(plink))
    {
        plink->phead = pdouble;
    }
    else
    {
        pdouble->pnext = plink->phead;
        plink->phead->ppre = pdouble;
        plink->phead = pdouble;
        
    }
    plink->clen++;
    return 0;
}
尾插
int push_doulink_end(Dlink_t *plink,DataType data)
{
    Dlink_node_t *pnode = malloc(sizeof(Dlink_node_t));
    if(NULL == pnode)
    {
        return -1;
    }

    pnode->data = data;
    pnode->ppre = NULL;
    pnode->pnext = NULL;

    if(is_empty_link(plink))
    {
        push_doulink_head(plink,data);
    }
    else
    {
        Dlink_node_t *p = plink->phead;
        while(p->pnext != NULL)
        {
            p = p->pnext;
        }
        p->pnext = pnode;
        pnode->ppre = p;
    }
    plink->clen++;
    return 0;
}
头删
int pop_link_head(Dlink_t *plink)
{
    Dlink_node_t *pnode = plink->phead;
    if(plink->phead ==NULL)
    {
        return 0;
    }
    else
    {
        Dlink_node_t *pdel = pnode;
        plink->phead = pnode->pnext;
        pnode->pnext->ppre = NULL;
        free(pdel);
    }
    plink->clen--;
    return 0;
}
尾删
int pop_link_end(Dlink_t *plink)
{
    Dlink_node_t *pnode = plink->phead;
    if(plink->phead == NULL)
    {
        return 0;
    }
    else if(pnode->pnext == NULL)
    {
        pop_link_head(plink);
    }
    else
    {
        while(pnode->pnext->pnext != NULL)
        {
            pnode = pnode->pnext;
        }
        pnode->pnext = NULL;
        free(pnode->pnext);
    }
    return 0;
}


http://www.kler.cn/a/290287.html

相关文章:

  • NVIDIA NIM 简介
  • 弹性盒子布局(Flexbox)详细介绍
  • 有什么初学算法的书籍推荐?
  • C++开发基础之使用librabbitmq库实现RabbitMQ消息队列通信
  • OpenEuler 下 Docker 安装、配置与测试实例
  • 「QT」几何数据类 之 QLine 整型直线类
  • 8逻辑回归的代价函数
  • HTTP与TCP的关系是什么?HTTP 的端口有什么意义?
  • ComfyUI SDXL Prompt Styler 简介
  • Android Studio Koala下载并安装,测试helloworld.
  • 惠中科技:以 RDS 光伏自清洁技术开启光伏电站新未来
  • 逻辑学(Logic)
  • Spring常用中间件
  • 智能分拣投递机器人
  • Python的socket库详细介绍
  • TOGAF之架构标准规范-架构愿景
  • Linux基础 -- pthread之线程池任务调度
  • Windows编程系列:PE文件结构
  • 【图论】Dijkstra算法求最短路
  • 【源码】Sharding-JDBC源码分析之ContextManager创建中ShardingSphereDatabase的创建原理
  • 注册安全分析报告:熊猫频道
  • centos 安装使用aria2
  • 数据分析处理库(pandas)
  • 802.11 中 scrambler的matlab仿真
  • Oracle中的临时表Temporary Table
  • [数据集][目标检测]课堂行行为检测数据集VOC+YOLO格式4065张12类别