单链表的建立、插入等替他操作见本人博客:

单链表的基本操作 http://10741357.blog.51cto.com/10731357/1736387

【面试题】单链表的操作1 http://10741357.blog.51cto.com/10731357/1736395

介绍了4种有关单链表的面试题,对于以下链表要求的实现,解题的思路很重要。例如两个有序链表的合并,实现约瑟夫环及链表成环问题。

各函数的实现,代码如下:

SListNode* MergeList(SListNode* L1, SListNode* L2)//合并两个有序链表,合并后依然有序
{//认为不带头结点的单链表,注意应判断两个链表是否为空if (L1 == NULL)return L2;if (L2 == NULL)return L1;//if (L1 || L2)//  return L1 = NULL ? L2 : L1;SListNode* NewHead = NULL;SListNode* pHead1 = L1;SListNode* pHead2 = L2;//进行一次比较,找出较小的值,使NewHead指向新链表的头结点if (pHead1->data < pHead2->data){NewHead = pHead1;pHead1 = pHead1->next;}else{NewHead = pHead2;pHead2 = pHead2->next;}//用tail指针进行比较和移动SListNode* tail = NewHead;while (pHead1 && pHead2){if (pHead1->data < pHead2->data){tail->next = pHead1;pHead1 = pHead1->next;}else{tail->next = pHead2;pHead2 = pHead2->next;}tail = tail->next;}//如果两个链表不一样长时,将其链接在新链表的后面if (pHead1)tail->next = pHead1;elsetail->next = pHead2;return NewHead;
}void BubbleSort(SListNode* pHead)//冒泡排序单链表
{
    if (pHead == NULL || pHead->next == NULL)
        return;
    int exchange = 0;//标志位判断排序是否已达到有序
    SListNode* tail = pHead->next;//比较n-1趟
    SListNode* tmp = NULL;//设置每趟的结束标志
    while (tail)
    {//两个指针cur,next进行比较和移动
        SListNode* cur = pHead;
        SListNode* next = pHead->next;

        while (cur->next != tmp)
        {
            if (cur->data > next->data)
            {
                exchange = 1;
                DataType tmp = cur->data;
                cur->data = next->data;
                next->data = tmp;
            }
            cur = cur->next;
            next = next->next;
        }
        if (exchange == 0)//如果没有发生交换,则链表已有序
            break;
        tail = tail->next;
        tmp = cur;//tmp指向cur,即下一趟比较在tmp处结束
    }
}SListNode* JosephCycle(SListNode* pHead, int k)//单链表实现约瑟夫环
{//判断链表及k是否有效if (pHead == NULL || k <= 0)return NULL;SListNode* cur = pHead;while (1){if (cur->next == cur)return cur;int count = k;while (--count)cur = cur->next;//替换法删除结点SListNode* next = cur->next;cur->data = next->data;cur->next = next->next;free(next);}return NULL;
}//判断单链表是否带环?若带环,求环长度,求环入口点
SListNode* CheckCycle(SListNode* pHead)//检查是否带环
{//利用快慢指针,慢指针走一步,快指针走两步;如果存在环,两个指针一定会相遇。if (pHead == NULL || pHead->next == NULL)return NULL;SListNode* slow = pHead;SListNode* fast = pHead;while (fast && fast->next)//条件为fast和fast->next都不为空{slow = slow->next;fast = fast->next->next;if (fast == slow)return slow;//如何带环返回相遇的结点}return NULL;
}int GetCycleLength(SListNode* MeetNode)//求环的长度
{//检查是否带环,即存在相遇点,走一圈就可以求出环的长度assert(MeetNode);SListNode* cur = MeetNode;int count = 0;do{count++;cur = cur->next;} while (cur != MeetNode);return count;
}SListNode* GetEntryNode1(SListNode* pHead)//求环的入口地址
{//检查是否有环,通过快慢指针分别从头结点和相遇结点处开始走,相遇点即为入口结点if (pHead == NULL || pHead->next == NULL)return NULL;SListNode* meetnode = CheckCycle(pHead);SListNode* slow = pHead;SListNode* fast = meetnode;while(slow && fast){if (slow == fast)return fast;slow = slow->next;fast = fast->next;}return NULL;
}int SListLength(SListNode* pHead)//分别求环形链表被拆成两条链表的链表长度
{if (pHead == NULL)return 0;int count = 0;SListNode* cur = pHead;while (cur){cur = cur->next;count++;}return count;
}SListNode* GetEntryNode2(SListNode* pHead)//求环的入口地址---两个链表相交思想
{//检查是否有环,在聚点处截断,求出两个链表相交点即为入口地址if (pHead == NULL || pHead->next == NULL)return NULL;SListNode* cur1 = pHead;SListNode* cur2 = CheckCycle(pHead)->next;CheckCycle(pHead)->next = NULL;//此法造成数据丢失int len1 = SListLength(cur1);int len2 = SListLength(cur2);PrintSList(cur1);printf("\n---------------------\n");PrintSList(cur2);int errand;//两个链表的长度差//长链表先走errand步if (len1 > len2){errand = len1 - len2;while (errand--)cur1 = cur1->next;}else{errand = len2 - len1;while (errand--)cur2 = cur2->next;}//两个链表同步前进while (cur1 != cur2){cur1 = cur1->next;cur2 = cur2->next;} return cur2;
}

各函数测试用例如下:

void Test10()
{//【面试题七】合并两个有序链表,合并后依然有序SListNode* phead1 = NULL;SListNode* phead2 = NULL;PushBack_Cpp(phead1, 1);PushBack_Cpp(phead1, 3);PushBack_Cpp(phead1, 6);PushBack_Cpp(phead2, 2);PushBack_Cpp(phead2, 4);PushBack_Cpp(phead2, 5);PushBack_Cpp(phead2, 7);SListNode* phead = MergeList(phead1,phead2);PrintSList(phead);printf("\n---------------------\n");
}void Test11()
{//【面试题八】冒泡排序单链表SListNode *phead = NULL;PushBack_Cpp(phead, 4);PushBack_Cpp(phead, 5);PushBack_Cpp(phead, 3);PushBack_Cpp(phead, 2);PushBack_Cpp(phead, 6);PushBack_Cpp(phead, 1);PrintSList(phead);printf("\n---------------------\n");BubbleSort(phead);PrintSList(phead);
}void Test12()
{//【面试题九】单链表实现约瑟夫环SListNode *phead = NULL;PushBack_Cpp(phead, 1);PushBack_Cpp(phead, 2);PushBack_Cpp(phead, 3);PushBack_Cpp(phead, 4);PushBack_Cpp(phead, 5);PushBack_Cpp(phead, 6);PrintSList(phead);printf("\n---------------------\n");Find(phead, 6)->next = Find(phead, 1);//将链表构成一个环,尾接头SListNode* FindNode = JosephCycle(phead,3);printf("%d\n",FindNode->data);
}void Test13()
{//【面试题十】判断单链表是否带环?若带环,求环长度,求环入口点SListNode *phead = NULL;PushBack_Cpp(phead, 1);PushBack_Cpp(phead, 2);PushBack_Cpp(phead, 3);PushBack_Cpp(phead, 4);PushBack_Cpp(phead, 5);PushBack_Cpp(phead, 6);PushBack_Cpp(phead, 7);PrintSList(phead);printf("\n---------------------\n");Find(phead, 6)->next = Find(phead, 3);SListNode* meetnode = CheckCycle(phead);//检查是否带环printf("%d\n", meetnode->data);if (meetnode==NULL)printf("该单链表不带环!\n");else{printf("该单链表带环!\n");int len = GetCycleLength(meetnode);//求环的长度printf("length = %d\n", len);SListNode* entry1 = GetEntryNode1(phead);//求环的入口地址printf("入口处为:%d\n", entry1->data);printf("\n---------------------\n");SListNode* entry2 = GetEntryNode2(phead);//求环的入口地址printf("\n入口处为:%d\n", entry2->data);}
}
int main()
{Test7();printf("\n***********************\n");Test8();printf("\n***********************\n");Test9();printf("\n***********************\n");Test10();printf("\n***********************\n");Test11();printf("\n***********************\n");Test12();printf("\n***********************\n");Test13();system("pause");
}

本文出自 “Scen” 博客,请务必保留此出处http://10741357.blog.51cto.com/10731357/1736403

【面试题】单链表的操作2相关推荐

  1. java实现单链表常见操作,java面试题,java初级笔试题

    写在最前面,我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家.扫码加微信好友进[程序员面试学习交流群],免费领取.也欢迎各位一起在群里探讨技术. 一. ...

  2. 笔试面试常考数据结构-单链表常用操作编程实现

    单链表是笔试以及面试手写代码中常考的数据结构之一.下面实现了单链表的常见操作:创建单链表.删除节点.打印单链表(包括正向打印以及逆向打印).反转单链表.找出单链表的倒数第K个节点.合并两个有序单链表等 ...

  3. java实现单链表常见操作

    一.概述: 本文主要总结单链表常见操作的实现,包括链表结点添加.删除:链表正向遍历和反向遍历.链表排序.判断链表是否有环.是否相交.获取某一结点等. 二.概念: 链表: 一种重要的数据结构,HashM ...

  4. 单链表创建及代码实现对单链表的操作

    链表:链表是一个有序的列表:是以节点的方式存储的,是链式存储:其中每一个节点包含data域,next域,next域指向下一个节点:链表的各个节点不一定是连续存放的:链表分带有头节点的链表和没有头节点的 ...

  5. 数据结构(5)之单链表的操作(补充)

    1 前言 上次我们讲到单链表的存储和一些简单的算法,今天我们来学习一下单链表的初始化和销毁操作. 2 详述 2.1 单链表的整表创建 思路: ·声明一结点p和计数器变量i; ·初始化一空链表L: ·让 ...

  6. c语言单链表数据显示,C++_C语言单链表常见操作汇总,C语言的单链表是常用的数据结 - phpStudy...

    #include #include //定义单链表结构体 typedef int ElemType; typedef struct Node { ElemType data; struct Node ...

  7. Java实现单链表反转操作

    单链表是一种常见的数据结构,由一个个节点通过指针方式连接而成,每个节点由两部分组成:一是数据域,用于存储节点数据.二是指针域,用于存储下一个节点的地址.在Java中定义如下: public class ...

  8. python 单链表的操作

    链表由一系列不必在内存中相连的结构构成,这些对象按线性顺序排序.每个结构含有表元素和指向后继元素的指针.最后一个单元的指针指向NULL.为了方便链表的删除与插入操作,可以为链表添加一个表头. 单链表 ...

  9. 数据结构 - 单链表(百度面试题单链表的倒序打印)

    方法1:反转打印(但是会改变链表结构,不建议) https://blog.csdn.net/weixin_43736084/article/details/101939789 方法2:存入栈中,在出栈 ...

  10. 面试题----单链表实现栈

    编程实现下面的栈顶操作: class MyData {void push(data);void pop(&data);bool isEmpty(); }; 解析:显然这里需要实现栈的3种基本操 ...

最新文章

  1. jenkins自动化部署工具
  2. Android 10.0系统启动之init进程-[Android取经之路]
  3. python函数和方法的编写原则_跟老齐学Python之传说中的函数编写条规
  4. 关于JEECG 开源声明
  5. jquery easyui validatebox remote使用
  6. linux恢复deleted状态的文件,Linux恢复被删除的文件 How To Recover Deleted Files From Your Linux System ....
  7. 2022年考研数据结构_5 树
  8. 【剑指offer】面试题17、合并两个排序的链表
  9. java初级面试总结
  10. psp记忆棒测试软件,PSP记忆棒有问题?修复软件MS-Format帮你解忧
  11. 还在为满意的渐变色发愁吗?10+个网站帮你轻松实现
  12. MapReduce 基础案例 之 平均值 计算
  13. ROC曲线下面积的相关计算和检验
  14. 100天精通Andriod逆向——第4天:各种抓包工具学习
  15. Win2003启用硬件加速(DirectX,声显卡启用)
  16. 打开word2007总是出现配置进度_最新版斑马进度计划软件更新了哪些功能?一起来探索 !...
  17. 操作系统:Linux进程与线程
  18. 《数据库系统》(六)物理数据库设计
  19. Python模块之paramiko
  20. CCPC-Wannafly Comet OJ 夏季欢乐赛(2019)部分题解

热门文章

  1. 亭子早期博客中16进制颜色值地址
  2. 新浪微博与微信公众号开发总结
  3. 计算机科学技术的广告语,让人动心的十大经典IT广告语
  4. XGBoost资料( 多届竞赛冠军获得者 周耀 整理)
  5. 学好Linux运维决心书
  6. 【数据结构】串(定长顺序串、堆串、块链串)的存储结构及基本运算(C语言)
  7. 知到网课大学生安全文化考试试题|真题|题库(含答案)
  8. 历代iPhone的分辨率
  9. python的编码解码是什么意思_python - 这是什么编码,如何解码
  10. 科学万能科计算机科学万能计算机,万能科学计算器CalcES v5.0.5脱壳专业会员版...