首页 > 其他分享 >k 栈排序随记

k 栈排序随记

时间:2023-12-25 20:56:35浏览次数:38  
标签:出栈 压入 元素 栈顶 权值 序列 排序 随记

定义

给出序列 \(a\),现有初始为空的序列 \(b\) 和 \(k\) 个初始为空的栈,你可以进行任意次以下两种操作:

  1. 选择 \(x\),若序列 \(a\) 非空,将 \(a_1\) 压入栈 \(x\),并将其从序列 \(a\) 中删除。

  2. 选择 \(x\),若栈 \(x\) 非空,将栈 \(x\) 的栈顶元素加至序列 \(b\) 末端,并将其弹出。

若存在一种操作方案,使得无法进行任何操作时序列 \(b\) 单调不降,则称 \(a\) 是可 \(k\) 栈排序的。

判定

对于长度为 \(n\) 的序列 \(a\),若有 \(i < j < k\) 满足 \(a_k < a_i < a_j\) 则连无向边 \((i, j)\)。

记最终得到的图为 \(G\),\(a\) 是可 \(k\) 栈排序的当且仅当 \(G\) 是 \(k\) 部图。

必要性

考虑反证。

若 \(G\) 不是 \(k\) 部图且 \(a\) 是可 \(k\) 栈排序的,则在操作方案中必有 \(i < j < k\) 满足 \(a_k < a_i < a_j\),且 \(a_i, a_j\) 被压入同一个栈。

当 \(a_j\) 被压入该栈时,因为 \(a_i < a_j\) 所以 \(a_i\) 必然已经出栈。此时 \(a_k\) 还未入栈,又因为 \(a_k < a_i\) 所以最终的 \(b\) 不可能单调不降,矛盾。

充分性

考虑构造证明。

找出 \(G\) 的一种 \(k\) 染色方案使得相邻的节点不同色,钦定颜色为 \(x\) 的节点对应的元素被压入栈 \(x\)。

当序列 \(a\) 非空时,不断将 \(a_1\) 压入对应的栈。

在把权值为 \(y\) 的元素压入栈 \(x\) 前,如果栈 \(x\) 非空且栈顶元素权值 \(z < y\),则不断弹出栈顶。在把权值为 \(z\) 的栈顶元素弹出栈 \(x\) 前,如果其它栈不全为空且最小栈顶元素权值 \(< z\),则不断弹出该最小栈顶。

序列 \(a\) 为空后,如果存在非空栈则不断弹出最小栈顶元素。

我们声称通过上述操作得到的序列 \(b\) 单调不降。

要证明序列 \(b\) 单调不降,只需证明每个元素出栈前所有权值严格小于它的元素已经出栈。

显然上述操作中每个元素出栈时它的权值都不大于还在栈中的任何元素,因此只需证明每个元素出栈时所有权值严格小于它的元素都已经入栈。

若权值为 \(z\) 的元素从栈 \(x\) 弹出:

如果该元素是因为一个权值为 \(y\) 的元素被压入栈 \(x\) 而弹出的,则必有 \(z < y\)。又因为这两个元素对应节点在 \(G\) 中不相邻,所以所有未入栈的元素权值都 \(\ge z\)。

如果该元素是因为一个权值为 \(y\) 的栈顶元素出栈而被弹出的,则必有 \(z < y\)。由上一段所有未入栈元素权值都 \(\ge y\),因此所有未入栈的元素权值都 \(> z\)。

否则该元素是在序列 \(a\) 为空后被弹出的,没有未入栈的元素。

例题

POI2010 KOL-Railway

kczno1 的题解,如果没看懂可以参考一下 我在 POI2003 Mortorways 的题解

标签:出栈,压入,元素,栈顶,权值,序列,排序,随记
From: https://www.cnblogs.com/JCY-std/p/17926954.html

相关文章

  • 直接插入排序
    直接插入排序是一种简单的排序方法,具体做法是:在插入第i个关键码时,k1,k2,...,ki-1已经排好序,这时将关键码ki依次与关键码ki-1,ki-2,...,进行比较,找到ki应该插入的位置时停下来,将插入位置及其后的关键码依次向后移动,然后插入ki。下面函数insertSort用直接插入排序对整数序列进行升序......
  • STM32采集传感器数据通过冒泡排序取稳定值
    STM32采集传感器数据通过冒泡排序取稳定值一、前言在物联网、单片机开发中,经常需要采集各种传感器的数据。比如:温度、湿度、MQ2、MQ3、MQ4等等传感器数据。这些数据采集过程中可能有波动,偶尔不稳定,为了得到稳定的值,我们可以对数据多次采集,进行排序,去掉最大......
  • oracle中排序分析函数row_number()、rank()、dense_rank() 的区别
    row_number()产生的序号不会重复,即1、2、3...rank()产生的序号会重复,但是会跳号,出现1、2、2、4...的情况dense_rank()产生的序号会重复,不会跳号,会出现1、2、2、3的情况而普通的rownum是一个伪列,与你的orderby是没有关系的SELECTrow_number()over(ORDERBYac.check_number......
  • 7-2 非递归二路归并排序
    7-2非递归二路归并排序本题目要求读入N个整数,采用非递归的二路归并排序法进行排序,输出前3轮排序后的结果。输入格式:输入不超过100的正整数N和N个整数(空格分隔)。输出格式:输出三行,第一行为第一轮排序结果,第二行为第二轮排序结果,第三行为第三轮排序结果。数据间用一个空格分......
  • 7-2 非递归二路归并排序
    7-2非递归二路归并排序本题目要求读入N个整数,采用非递归的二路归并排序法进行排序,输出前3轮排序后的结果。输入格式:输入不超过100的正整数N和N个整数(空格分隔)。输出格式:输出三行,第一行为第一轮排序结果,第二行为第二轮排序结果,第三行为第三轮排序结果。数据间用一个空格分......
  • 7-1 递归二路归并排序
    7-1递归二路归并排序本题目要求读入N个整数,采用递归的二路归并排序法进行排序,输出前3轮排序后的结果。输入格式:输入不超过100的正整数N和N个整数(空格分隔)。输出格式:输出三行,第一行为第一轮排序结果,第二行为第二轮排序结果,第三行为第三轮排序结果。数据间用一个空格分隔。......
  • 7-2 非递归二路归并排序
    7-2非递归二路归并排序本题目要求读入N个整数,采用非递归的二路归并排序法进行排序,输出前3轮排序后的结果。输入格式:输入不超过100的正整数N和N个整数(空格分隔)。输出格式:输出三行,第一行为第一轮排序结果,第二行为第二轮排序结果,第三行为第三轮排序结果。数据间用一个空格分......
  • 详解十大经典排序算法(六):快速排序(QuickSort)
    算法原理分区(Partition):选择一个基准元素,将数组分为两个子数组,小于基准的放在左边,大于基2准的放在右边。递归排序:对左右两个子数组分别进行快速排序。合并:不需要实际的合并操作,因为在分解和递归排序阶段已经完成了排序。算法描述快速排序是一种基于分治思想的高效排序算法,由英国......
  • 算法学习笔记五一快速排序
    目录什么是快速排序算法思想示例代码什么是快速排序快速排序(Quicksort)是一种常用的排序算法,它的基本思想是通过分治的策略将一个大问题划分为多个小问题来解决。它的平均时间复杂度为O(nlogn),最坏情况(有序情况)为O(n^2)。是一种高效的排序算法。算法思想选择一个基准元素(pivot......
  • 将 n 个整数由小到大排序
    #define_CRT_SECURE_NO_WARNINGS1#include<stdio.h>intmain(){ intarr[10]; printf("请输入一串数字:\n"); for(inti=0;i<10;i++) { scanf("%d",&arr[i]); } for(inti=0;i<10;i++)//循环次数等于元素 { for(intj=......