热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

单链表的基础知识

        单链表的基础知识主要包括链表节点的删除、链表节点的插入、链表的排序、链表的逆置、寻找链表的中间节点、寻找链表的倒数第m个节点,本文主要是用代码对这些基础问题进行了实

         单链表的基础知识主要包括链表节点的删除、链表节点的插入、链表的排序、链表的逆置、寻找链表的中间节点、寻找链表的倒数第m个节点,本文主要是用代码对这些基础问题进行了实现。

typedef struct node{
            int data;
            node *next;
        }node;

  • 节点的删除

     

 1 node *remove(node *head,const int &target)
 2 {
 3     node *p1,*p2;
 4     p1=head;
 5     while (p1->data!=target && p1->next!=NULL)
 6     {
 7         p2=p1;
 8         p1=p1->next;
 9     }
10     if (target==p1->data)
11     {
12         if (p1==head)
13         {
14             head=p1->next;
15             free(p1);
16         }
17         else
18         {
19             p2->next=p1->next;
20             free(p1);
21         }
22     }
23     else
24     {
25         cout<<"The list dosen't include the target."<<endl;
26     }
27 
28     return head;
29 
30 }
  • 节点的插入
 1 node *insertNoHead(const node *head,node *prevoiusPtr,const int &target)
 2 {
 3     node *insertPtr;
 4     insertPtr=new node;
 5     insertPtr->data=target;
 6     insertPtr->next=prevoiusPtr->next;
 7     prevoiusPtr->next=insertPtr;
 8     return head;
 9 }
10 
11 node *insertHead(node *&head,const int &target)
12 {
13     node *insertPtr;
14     insertPtr=new node;
15     insertPtr->next=head;
16     head=insertPtr;
17     return head;
18 }
  • 单链表的排序
 1 node *sort(node *head)
 2 {
 3     node *p,*p1,*p2;
 4     int n;
 5     int temp;
 6     n=length(head);
 7     if (head==NULL || head->next==NULL)
 8     {
 9         return head;
10     }
11     else
12     {
13         p=head;
14         for (int j=1;j)
15         {
16             p=head;
17             for (int i=0;i)
18             {
19                 if (p->data>p->next->data)
20                 {
21                     temp=p->data;
22                     p->data=p->next->data;
23                     p->next->data=temp;
24                 }
25                 p=p->next;
26             }
27         }
28         return head;
29     }
30     
31 }

 

  • 链表的长度
 1 int length(node *head)
 2 {
 3     int sum=0;
 4     while(head)
 5     {
 6         sum++;
 7         head=head->next;
 8     }
 9     return sum;
10     
11 }
  • 链表的逆置
 1 node *reverse(node *head)
 2 {
 3     node *p1,*p2,*p3;
 4     if (head==NULL || head->next==NULL)
 5     {
 6         return head;
 7     }
 8     else
 9     {
10         p1=head;
11         p2=p1->next;
12         while(p2)
13         {
14             p3=p2->next;
15             p2->next=p1;
16             p1=p2;
17             p2=p3;
18 
19         }
20         head->next=NULL;
21         head=p1;
22         return head;
23     }
24 }
  • 寻找单链表的中间节点

       首先设置两个指针p1和p2都指向头指针,然后p1指针一次走一步,p2指针一次走两步,当p2走到单链表的末尾时,此时p1所指向的节点即为中间节点。

 

 1 node *searchMiddle(node *head)
 2 {
 3     node *p1,*p2;
 4     p1=p2=head;
 5     int n=length(head);
 6     if(n<3)
 7     {
 8         return head;
 9     }
10     else
11     {
12         while(p2->next && p2->next->next)
13         {
14             p2=p2->next->next;
15             p1=p1->next;
16 
17         }
18         return p1;
19     }
20 }
  • 寻找但链表中倒数第m个节点

     方法一:首先求出单链表总的长度n,然后从链表的头节点开始遍历,当遍历到n-m个节点时,即为链表中倒数第m个节点。

node *FindReverseM1(node *head,int m)
{
    node *p;
    int n=length(head);
    if (n==0 || m>n)
    {
        return NULL;
    }
    
    p=head;
    for(int i=0;i)
    {
        p=p->next;
    }
    return p;
}

   方法二:首先设置两个指针p1和p2,同时指向单链表的头节点,然后用p2遍历链表,将p2指向链表中第m个节点,接着将p1和p2同时进行遍历,当p2指向链表中末尾节点时,p1所指向的节点即为倒数第m个节点。

 1 node *FindReverseM2(node *head,int m)
 2 {
 3     node *p1,*p2;
 4     int n=length(head);
 5     if (n==0 || n<m)
 6     {
 7         return NULL;
 8     }
 9     p1=p2=head;
10     for (int i=0;i)
11     {
12         p2=p2->next;
13     }
14     while(p2)
15     {
16         p2=p2->next;
17         p1=p1->next;
18     }
19     return p1;
20 }

 


推荐阅读
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 本文介绍了指针的概念以及在函数调用时使用指针作为参数的情况。指针存放的是变量的地址,通过指针可以修改指针所指的变量的值。然而,如果想要修改指针的指向,就需要使用指针的引用。文章还通过一个简单的示例代码解释了指针的引用的使用方法,并思考了在修改指针的指向后,取指针的输出结果。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
author-avatar
手机用户2502879933
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有