【面试准备 算法题】用快排的思路对单链表进行排序(不能进行值拷贝)

这篇具有很好参考价值的文章主要介绍了【面试准备 算法题】用快排的思路对单链表进行排序(不能进行值拷贝)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

最近面试碰到这个题目感觉很有意思,既考察二分/递归的思想,也考察链表的操作,尤其对于边界情况的处理需要细心文章来源地址https://www.toymoban.com/news/detail-645383.html

题目要求

struct LinkNode {
  LinkNode() : val(0), next(nullptr) { }
  LinkNode(int v) : val(v), next(nullptr) { }

  int val;
  LinkNode* next;
};
  1. 给定单链表进行排序(链表节点定义如上)
  2. 不能通过值拷贝来实现元素交换(必须通过修改next指针实现 元素位置排序 )

实现

#include <vector>
#include <iostream>

/**
 * LinkList Uitil Functions
 * 
 **/ 
// ========================================================================
struct LinkNode {
  LinkNode() : val(0), next(nullptr) { }
  LinkNode(int v) : val(v), next(nullptr) { }

  int val;
  LinkNode* next;
};

LinkNode* CreateLinkList(const std::vector<int>& nums) {
  LinkNode head;
  LinkNode* tmp = &head;

  for (const auto& num : nums) {
    tmp->next = new LinkNode(num);
    tmp = tmp->next;
  }

  return head.next;
}

void PrintLinkList(LinkNode* head) {
  while (head != nullptr) {
    std::cout << head->val << " ";
    head = head->next;
  }
  std::cout << std::endl;
}
// ========================================================================


// return <head, tail>;
std::pair<LinkNode*, LinkNode*> LinkSort(LinkNode* head, LinkNode* tail) {
  if (head == nullptr || head == tail ) return { head, tail };

  // first store it, in case be modfied
  auto tail_next = tail->next;

  // 1. Get mid node;
  int mid_val = head->val;

  // 2. Travel and split link list;
  LinkNode left_dummy;
  LinkNode right_dummy;

  LinkNode* left = &left_dummy;
  LinkNode* right = &right_dummy;

  auto tmp = head->next;

  while (tmp != tail_next) {
    if (tmp->val < mid_val) {
      left->next = tmp;
      left = left->next;
    } else {
      right->next = tmp;
      right = right->next;
    }
    tmp = tmp->next;
  }

  // 3. Recursive sort
  auto lpair = LinkSort(left_dummy.next, left);
  auto rpair = LinkSort(right_dummy.next, right);

  // 4. Merge sorted list;
  LinkNode* sorted_head = nullptr;
  LinkNode* sorted_tail = nullptr;

  if (lpair.first == nullptr) {
    sorted_head = head;
  } else {
    sorted_head = lpair.first;
    lpair.second->next = head;
  }

  if (rpair.first == nullptr) {
    head->next = tail_next;
    sorted_tail = head;
  } else {
    head->next = rpair.first;
    rpair.second->next = tail_next;
    sorted_tail = rpair.second; 
  }

  return { sorted_head, sorted_tail };
}

LinkNode* LinkSort(LinkNode* head) {
  auto tail = head;

  while(tail->next != nullptr) {
    tail = tail->next;
  }

  return LinkSort(head, tail).first;
}

int main() {
  std::vector<int> nums = { 5, 4, 3, 2, 1 };
  auto head = CreateLinkList(nums);

  auto sorted_head = LinkSort(head);
  PrintLinkList(sorted_head);

  return 0;
}

到了这里,关于【面试准备 算法题】用快排的思路对单链表进行排序(不能进行值拷贝)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】单链表经典算法题的巧妙解题思路

    目录 题目 1.移除链表元素 2.反转链表 3.链表的中间节点 4.合并两个有序链表 5.环形链表的约瑟夫问题 解析 题目1:创建新链表 题目2:巧用三个指针 题目3:快慢指针 题目4:哨兵位节点 题目5:环形链表   介绍完了单链表,我们这次来说几个经典的题目,本篇的题目衔接下一

    2024年04月28日
    浏览(63)
  • 春招面试准备笔记——NMS(非极大值抑制)算法

    NMS(非极大值抑制)算法非极大值抑制是用于减少物体检测算法中重叠边界框或区域的数量的技术。通过对每个类别的检测框按置信度排序,然后逐个遍历,保留置信度最高的框,并抑制与其重叠且置信度低的框,从而得到更准确和简洁的检测结果。 假设我们使用一个人脸检

    2024年02月21日
    浏览(62)
  • 三路快排Java版(带思路分析)

    这里我们直接开始讲相对的最优解 带随机数的三路快排 好了,中间还有很多版本的快排,但是都有一些问题导致在某种极端情况下造成耗费时间极多。 基础快排:在 序列本身有序 的情况下复杂度为O(n²) 带随机数的快排:在 序列本身有序 的情况下复杂度为O(nlogn),但

    2024年02月06日
    浏览(34)
  • 算法刷题营【Day3】:: 链表篇:单链表结点删除思路:一题辨别哨兵结点的优势(删除有奇效):203. 移除链表元素

    本内容是笔者结合《代码随想录》总结所得,记录学习过程,分享知识! 目录: 1. 开篇例题:203. 移除链表元素 2. 题解参考 - - 2.1 方法一:原表操作(不含哨兵结点) - - 2.2 方法二:虚设哨兵结点辅助法 - - 2.3 方法三:递归法 3. 单链表结点删除思路 4. 方法思路点拨:原表操

    2024年02月06日
    浏览(49)
  • 【我们一起60天准备考研算法面试(大全)-第二十九天 29/60】【二进制】

    专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录) 文章字体风格: 红色文字表示:重难点★✔ 蓝色文字表示:思路以及想法★✔ 如果大家觉得有帮助的话,感谢大家帮

    2024年02月15日
    浏览(51)
  • 【考研思维题】【哈希表 || 什么时候用哈希表呢?快速查询的时候】【我们一起60天准备考研算法面试(大全)-第九天 9/60】

    专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录) 文章字体风格: 红色文字表示:重难点★✔ 蓝色文字表示:思路以及想法★✔ 如果大家觉得有帮助的话,感谢大家帮

    2024年02月13日
    浏览(54)
  • 单链表面试题思路分享二

    我们紧接上文单链表面试题分享一来看看本章我要分享的题目,共四个题目,我还是把它在力扣或者牛客网的链接交给大家: 1.合并两个有序链表 力扣21题----- 2.链表的分割 牛客网cc149----- 3.链表的回文结构 力扣234题----- 4.链表相交 力扣160题, 本次分享还是和之前一样,代码用c语言

    2023年04月23日
    浏览(52)
  • 带头节点的单链表的思路及代码实现

    单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) +指针(指示后继元素存储位置,元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。) 以上是

    2023年04月08日
    浏览(41)
  • 快排算法(分治法)

            相信很多人接触到的第一个排序就是冒泡排序,冒泡排序是一种拿一个数依次和后面进行比较,这样也就确保了每一次排序之后不论降序还是升序这一个数都会在末尾或者最前端,那么今天我们要将的是快速排序,基于冒泡排序的改进版本,为什么说是改进呢。要

    2024年02月16日
    浏览(33)
  • 【算法】分治-快排

    个人主页 : zxctscl 如有转载请先通知 分治就是分而治之 就是把数组中的元素分为三块,0全部在左边,1全部在中间,2全部在右边。 这里要用到三个指针,一个i指针用来遍历,一个left用来存放0区域的最后侧,一个用来存放2区域的最左侧。 那么区间就分成了4个 只需要判断

    2024年04月25日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包