单链表属于基本数据结构中的线性结构,它应用于很多数据结构中,例如栈,队列等,作用广泛。在数据结构中我们习惯把关于单链表的一系列操作制作为一个ADT(Abstract Data Type)使用,在C++中把它封装为一个类,使用起来更是方便。

关于单链表的操作包括插入(包括头插和尾插)、删除、查找、检查是否有环、环的长度、环的入口等操作。以下就是我的代码实现:
每个结点的数据类型应该是一个结构体类型:

struct Node
{Node(int data=0){_data = data;_pnext = NULL;}int _data;Node *_pnext;

单链表类的定义:


class LinkList
{
public:LinkList(){_head = new Node;cout<<"LinkList()"<<endl;}~LinkList(){if (_head == NULL){return;}if (isLoop()){Node *tmp = _head->_pnext;Node *p = NULL;while (tmp != getFirstLoopNode()){    tmp = tmp->_pnext;  }tmp->_pnext = NULL;}Node *tmp = _head->_pnext;Node *p = NULL;while (tmp != NULL){p = tmp;tmp = tmp->_pnext;delete p;    }delete _head;cout<<"~LinkList()"<<endl;}void insertHead(int data){Node *tmp = new Node(data);tmp->_pnext = _head->_pnext;_head->_pnext = tmp;}void insertTail(int data){Node *tmp = _head->_pnext;while (tmp->_pnext != NULL){tmp = tmp->_pnext;}tmp->_pnext = new Node(data);tmp->_pnext->_pnext = NULL;}void deleteData(int data){Node *tmp = _head->_pnext;Node *p = _head;while (tmp->_data != data && tmp->_pnext != NULL){p = tmp;tmp = tmp->_pnext;}p->_pnext = tmp->_pnext;delete tmp;}void show(){Node *tmp = _head->_pnext;while (tmp != NULL){cout<<tmp->_data<<" ";tmp = tmp->_pnext;}cout<<endl;}//是否有环bool isLoop(){Node*fast = _head;Node*slow = _head;while (fast != NULL && fast->_pnext != NULL){fast = fast->_pnext->_pnext;slow = slow->_pnext;if (fast == slow){return true;}}return false;}void creat_loop()//创建有环链表{Node *tmp = _head->_pnext;while (tmp->_pnext != NULL){tmp = tmp->_pnext;}tmp->_pnext = _head->_pnext;}//获取单链表环的第一个节点Node* getFirstLoopNode(){Node *fast = _head;Node *slow = _head;while (fast != NULL && fast->_pnext != NULL)//快指针走的步数是慢指针走的步数的两倍{fast = fast->_pnext->_pnext;slow = slow->_pnext;if (fast == slow){break;}}slow = _head;while (slow != fast){slow = slow->_pnext;}return slow;}//获取环的长度int getLoopLength(){Node *fast = _head;Node *slow = _head;while (fast != NULL && fast->_pnext != NULL){fast = fast->_pnext->_pnext;slow = slow->_pnext;if (fast == slow){break;}}slow = slow->_pnext;int count = 1;while (slow != fast){slow = slow->_pnext;count++;}return count;}
private:Node *_head;
};
int main()
{
LinkList list;
for (int i=0;i<4;i++)
{
list.insertHead(rand()%10);
}
list.show();
for (int i=1;i<6;i++)
{
list.insertTail(i*10);
}
list.deleteData(0);
list.show();
list.creat_loop();
if (list.isLoop())
{
cout<<"have a loop"<<endl;
cout<<"loop entrance:"<<list.getFirstLoopNode()->_data<<endl;
cout<<"loop length:"<<list.getLoopLength()<<endl;
}
return 0;
}

判断链表是否有环,通常的办法就是使用快慢指针,快慢指针初始时指向同一个位置,这里指向头结点(fast = _head;slow = _head);快指针每次向前走两步(fast = fast->_pnext->_pnext;),慢指针每次走一步( slow = slow->_pnext;);当快指针遇到慢指针时,说明该链表有环。
      计算环的长度,在环上相遇后,记录第一次相遇点为fast=slow,添加计数器count=0;fast不动,slow每次走一步,count++,等到fast==slow时,count的值就是环的长度。
      判断环的入口,假设头结点距离环的入口的距离是len,在环上相遇时,假设slow走了S步,则fast走了2S步,并且2S=S+len,即S=len,所以当fast和slow相遇时,slow从头结点出发,当遇到fast时的位置就是环的入口结点。
      上述代码中由于创建了有环的链表,所以在析构函数中添加了有环链表的析构过程,相对来说,这个链表还不算完整,比如对有环链表的插入结点、删除结点以及打印结点信息的方法都未实现,原理上与析构的过程其实是一致的,基本原理懂了,一切都so easy了。*^_^*

C++实现带头结点单链表相关推荐

  1. 在带头结点单链表中查找最大值,将其与最后一个元素交换(交换值)

    [问题描述] 在带头结点单链表中查找最大值,将其值与最后一个元素交换,输出交换后的单链表各元素. [输入形式] 循环输入若干个整数,以字母结束输入,建立带头结点的单链表. [输出形式] 输出最大值与最 ...

  2. 小白算法积累——单链表6#带头结点单链表+递增有序

    题目:有一个带头结点的单链表L,设计一个算法使其元素递增有序. 关键字:带头结点单链表+递增有序 思路 采用直接插入排序算法的思想:就是先分理出头结点+第一个结点组成原始新链表,然后依次将后续结点摘下 ...

  3. 算法与数据结构之带头结点和不带头结点单链表存在的问题

    带头结点和不带头结点单链表注意的小细节 在写不带头结点的单链表中发现了一个问题,这个问题在带头结点的单链表中也存在,那就是值传递的问题. 首先来看一下 #include<stdio.h> ...

  4. 【问题描述】在带头结点单链表中查找最大值,将其值与最后一个元素交换,输出交换后的单链表各元素。【输入形式】循环输入若干个整数,以字母结束输入,建立带头结点的单链表。【输出形式】输出最

    [问题描述] 在带头结点单链表中查找最大值,将其值与最后一个元素交换,输出交换后的单链表各元素. [输入形式] 循环输入若干个整数,以字母结束输入,建立带头结点的单链表. [输出形式] 输出最大值与最 ...

  5. 数据结构之不带头结点单链表和带头结点单链表相关操作实现(C语言)

    文章目录 单链表定义 不带头结点单链表 带头结点单链表 头结点和头指针的区分 带头结点单链表优点 单链表定义 线性表的链式存储又称单链表,它是指通过一组任意的存储单元来存储线性表中的数据元素. 不带头 ...

  6. 带头结点单链表的基本使用

    1.功能说明: 1.带头结点单链表的创建      2.单链表头插      3.单链表尾插      4.单链表第i个位置插入      5.单链表输出      6.单链表删除第i个位置结点   ...

  7. #数据结构:编写不带头结点单链表的建立、插入和删除算法

    编写不带头结点单链表的建立.插入和删除操作算法. 一.问题描述 编写一个不带头节点的单链表 二.基本要求 1) 建立 2) 插入 3) 删除 三.算法思想 选用不带头结点的单链表,在第一个元素节点前插 ...

  8. java带头结点空单链表_Java版带头结点单链表的实现

    Java版带头结点单链表的实现 Java版带头结点单链表的实现 package dsr; public interface IList { public void clear();//8 public ...

  9. 带头结点单链表递增有序

    怎么说呢,思路很简单很简单,先把头结点拆出来,后边的结点继续遍历,向头结点中插入,只不过插入的时候有了一点条件而已(需要有序),但是!!感觉一点也不简单呢,指针一直变,还是有点混乱的. 慢慢熟悉一下加 ...

  10. 小白算法积累——单链表13#带头结点单链表+就地归并+改序

    题目:假设有两个按元素值递增次序排列的线性表,均以单链表的形式存储.请编写算法将这两个单链表归并为一个按元素值递减次序排列的单链表,并要求利用原来两个单链表的结点存放归并后的单链表. 关键字:带头结点 ...

最新文章

  1. Nginx Http 过滤模块
  2. 在ASP.Net2.0中使用UrlRewritingNet实现链接重写
  3. 产品团队的批判性思维:如何通过合理的决策带来合理的结果?
  4. 项目整体管理:指导和管理项目工作
  5. 【电路补习笔记】4、二极管的参数与选型
  6. linux svn 服务 关闭,Linux下启动、关闭SVN服务
  7. 澳大利亚计算机领域的科学家,澳科学家首创硅基元件 突破量子计算机制造瓶颈...
  8. Linux学习之二十、循环
  9. 63. (FileInputStream)输入字节流
  10. 转太强了!一文讲透了标准Web系统的架构分层~
  11. 计算机网络教程网线制作,网线制作方法 图文解析教你学会制作网线【图文教程】...
  12. MAC快捷键还原最小化的(cmd+M)程序窗口
  13. 为什么你一直学不好SEO优化?
  14. Google工具包Guava——聊聊代码校验Preconditions
  15. 天气图标下载_50种免费天气图标集可供下载
  16. Halcon实战 项目二 Bolb实战分析-提取图片中的硬币
  17. linux C/C++ 后端服务问题排查(gdb, pstack,valgrind)
  18. 光电二极管的采样电路
  19. 卓别林论Scrum价值观:当我真正开始爱自己
  20. w ndows10装什么浏览器,win10怎么重装ie浏览器

热门文章

  1. 自然辨证法推荐书目--100本,够看好几个学期了
  2. keil模拟仿真设置
  3. websocket安全分析
  4. 关于Ubuntu下Komodo如何运行
  5. 无人驾驶技术个人理解
  6. MTK 调试的奇巧淫技
  7. 【dubbo】springboot集成dubbo框架
  8. python三门问题_如何用Python解决蒙特霍尔三门问题
  9. RiDoc(电脑扫描仪软件)官方中文版V5.0.8.8 | ridoc使用方法简单
  10. 入门机器学习的必备Python基础