C
int pancake_sort(int *list, unsigned int length)
{
//If it's less than 2 long, just return it as sorting isn't really needed...
if(length<2)
return 0;
int i,a,max_num_pos,moves;
moves=0;
for(i=length;i>1;i--)
{
//Find position of the max number in pos(0) to pos(i)
max_num_pos=0;
for(a=0;a<i;a++)
{
if(list[a]>list[max_num_pos])
max_num_pos=a;
}
if(max_num_pos==i-1)
//It's where it need to be, skip
continue;
//Get the found max number to the beginning of the list (unless it already is)
if(max_num_pos)
{
moves++;
do_flip(list, length, max_num_pos+1);
}
//And then move it to the end of the range we're working with (pos(0) to pos(i))
moves++;
do_flip(list, length, i);
//Then everything above list[i-1] is sorted and don't need to be touched
}
return moves;
}
void do_flip(int *list, int length, int num)
{
int swap;
int i=0;
for(i;i<--num;i++)
{
swap=list[i];
list[i]=list[num];
list[num]=swap;
}
}
C++
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
// pancake sort template (calls predicate to determine order)
template <typename BidIt, typename Pred>
void pancake_sort(BidIt first, BidIt last, Pred order)
{
if (std::distance(first, last) < 2) return; // no sort needed
for (; first != last; --last)
{
BidIt mid = std::max_element(first, last, order);
if (mid == last - 1)
{
continue; // no flips needed
}
if (first != mid)
{
std::reverse(first, mid + 1); // flip element to front
}
std::reverse(first, last); // flip front to final position
}
}
// pancake sort template (ascending order)
template <typename BidIt>
void pancake_sort(BidIt first, BidIt last)
{
pancake_sort(first, last, std::less<typename std::iterator_traits<BidIt>::value_type>());
}
int main()
{
std::vector<int> data;
for (int i = 0; i < 20; ++i)
{
data.push_back(i); // generate test data
}
std::random_shuffle(data.begin(), data.end()); // scramble data
std::copy(data.begin(), data.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n";
pancake_sort(data.begin(), data.end()); // ascending pancake sort
std::copy(data.begin(), data.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n";
}
C#
public static class PancakeSorter
{
public static void Sort<T>(List<T> list) where T : IComparable
{
if (list.Count < 2)
{
return;
}
int i, a, max_num_pos;
for (i = list.Count; i > 1; i--)
{
max_num_pos = 0;
for (a = 0; a < i; a++)
{
if (list[a].CompareTo(list[max_num_pos]) > 0)
{
max_num_pos = a;
}
}
if (max_num_pos == i - 1)
{
continue;
}
if (max_num_pos > 0)
{
Flip(list, list.Count, max_num_pos + 1);
}
Flip(list, list.Count, i);
}
return;
}
private static void Flip<T>(List<T> list, int length, int num)
{
for (int i = 0; i < --num; i++)
{
T swap = list[i];
list[i] = list[num];
list[num] = swap;
}
}
}
Go
package main
import "fmt"
func main() {
list := pancake{31, 41, 59, 26, 53, 58, 97, 93, 23, 84}
fmt.Println("unsorted:", list)
list.sort()
fmt.Println("sorted! ", list)
}
type pancake []int
func (a pancake) sort() {
for uns := len(a) - 1; uns > 0; uns-- {
// find largest in unsorted range
lx, lg := 0, a[0]
for i := 1; i <= uns; i++ {
if a[i] > lg {
lx, lg = i, a[i]
}
}
// move to final position in two flips
a.flip(lx)
a.flip(uns)
}
}
func (a pancake) flip(r int) {
for l := 0; l < r; l, r = l+1, r-1 {
a[l], a[r] = a[r], a[l]
}
}
Java
public class PancakeSort
{
int[] heap;
public String toString() {
String info = "";
for (int x: heap)
info += x + " ";
return info;
}
public void flip(int n) {
for (int i = 0; i < (n+1) / 2; ++i) {
int tmp = heap[i];
heap[i] = heap[n-i];
heap[n-i] = tmp;
}
System.out.println("flip(0.." + n + "): " + toString());
}
public int[] minmax(int n) {
int xm, xM;
xm = xM = heap[0];
int posm = 0, posM = 0;
for (int i = 1; i < n; ++i) {
if (heap[i] < xm) {
xm = heap[i];
posm = i;
}
else if (heap[i] > xM) {
xM = heap[i];
posM = i;
}
}
return new int[] {posm, posM};
}
public void sort(int n, int dir) {
if (n == 0) return;
int[] mM = minmax(n);
int bestXPos = mM[dir];
int altXPos = mM[1-dir];
boolean flipped = false;
if (bestXPos == n-1) {
--n;
}
else if (bestXPos == 0) {
flip(n-1);
--n;
}
else if (altXPos == n-1) {
dir = 1-dir;
--n;
flipped = true;
}
else {
flip(bestXPos);
}
sort(n, dir);
if (flipped) {
flip(n);
}
}
PancakeSort(int[] numbers) {
heap = numbers;
sort(numbers.length, 1);
}
public static void main(String[] args) {
int[] numbers = new int[args.length];
for (int i = 0; i < args.length; ++i)
numbers[i] = Integer.valueOf(args[i]);
PancakeSort pancakes = new PancakeSort(numbers);
System.out.println(pancakes);
}
}
JavaScript
Array.prototype.pancake_sort = function () {
for (var i = this.length - 1; i >= 1; i--) {
// find the index of the largest element not yet sorted
var max_idx = 0;
var max = this[0];
for (var j = 1; j <= i; j++) {
if (this[j] > max) {
max = this[j];
max_idx = j;
}
}
if (max_idx == i)
continue; // element already in place
var new_slice;
// flip this max element to index 0
if (max_idx > 0) {
new_slice = this.slice(0, max_idx+1).reverse();
for (var j = 0; j <= max_idx; j++)
this[j] = new_slice[j];
}
// then flip the max element to its place
new_slice = this.slice(0, i+1).reverse();
for (var j = 0; j <= i; j++)
this[j] = new_slice[j];
}
return this;
}
ary = [7,6,5,9,8,4,3,1,2,0]
sorted = ary.concat().pancake_sort();
Kotlin
// version 1.1.2
class PancakeSort(private val a: IntArray) {
init {
for (n in a.size downTo 2) { // successively reduce size of array by 1
val index = indexOfMax(n) // find index of largest
if (index != n - 1) { // if it's not already at the end
if (index > 0) { // if it's not already at the beginning
flip(index) // move largest to beginning
println("${a.contentToString()} after flipping first ${index + 1}")
}
flip(n - 1) // move largest to end
println("${a.contentToString()} after flipping first $n")
}
}
}
private fun indexOfMax(n: Int): Int {
var index = 0
for (i in 1 until n) {
if (a[i] > a[index]) index = i
}
return index
}
private fun flip(index: Int) {
var i = index
var j = 0
while (j < i) {
val temp = a[j]
a[j] = a[i]
a[i] = temp
j++
i--
}
}
}
fun main(args: Array<String>) {
val a = intArrayOf(7, 6, 9, 2, 4, 8, 1, 3, 5)
println("${a.contentToString()} initially")
PancakeSort(a)
}
Perl
sub pancake {
my @x = @_;
for my $idx (0 .. $#x - 1) {
my $min = $idx;
$x[$min] > $x[$_] and $min = $_ for $idx + 1 .. $#x;
next if $x[$min] == $x[$idx];
@x[$min .. $#x] = reverse @x[$min .. $#x] if $x[$min] != $x[-1];
@x[$idx .. $#x] = reverse @x[$idx .. $#x];
}
@x;
}
my @a = map (int rand(100), 1 .. 10);
print "Before @a\n";
@a = pancake(@a);
print "After @a\n";
Perl 6
sub pancake_sort ( @a is copy ) {
my $endpoint = @a.end;
while $endpoint > 0 and not [<] @a {
my $max_i = [0..$endpoint].max: { @a[$_] };
my $max = @a[$max_i];
if @a[$endpoint] == $max {
$endpoint-- while @a[$endpoint] == $max;
next;
}
# @a[$endpoint] is not $max, so it needs flipping;
# Flip twice if max is not already at the top.
@a[0..$max_i] .= reverse if $max_i != 0;
@a[0..$endpoint] .= reverse;
$endpoint--;
}
return @a;
}
my @data = 6, 7, 2, 1, 8, 9, 5, 3, 4;
say 'input = ' ~ @data;
say 'output = ' ~ @data.&pancake_sort;
PowerShell
Function FlipPancake( [Object[]] $indata, $index = 1 )
{
$data=$indata.Clone()
$datal = $data.length - 1
if( $index -gt 0 )
{
if( $datal -gt $index )
{
$first = $data[ $index..0 ]
$last = $data[ ( $index + 1 )..$datal ]
$data = $first + $last
} else {
$data = $data[ $index..0 ]
}
}
$data
}
Function MaxIdx( [Object[]] $data )
{
$data | ForEach-Object { $max = $data[ 0 ]; $i = 0; $maxi = 0 } { if( $_ -gt $max ) { $max = $_; $maxi = $i }; $i++ } { $maxi }
}
Function PancakeSort( [Object[]] $data, $index = 0 )
{
"unsorted - $data"
$datal = $data.length - 1
if( $datal -gt 0 )
{
for( $i = $datal; $i -gt 0; $i-- )
{
$data = FlipPancake ( FlipPancake $data ( MaxIdx $data[ 0..$i ] ) ) $i
}
}
"sorted - $data"
}
$l = 100; PancakeSort ( 1..$l | ForEach-Object { $Rand = New-Object Random }{ $Rand.Next( 0, $l - 1 ) } )
Python
tutor = False
def pancakesort(data):
if len(data) <= 1:
return data
if tutor: print()
for size in range(len(data), 1, -1):
maxindex = max(range(size), key=data.__getitem__)
if maxindex+1 != size:
# This indexed max needs moving
if maxindex != 0:
# Flip the max item to the left
if tutor: print('With: %r doflip %i'
% ( ' '.join(str(x) for x in data), maxindex+1 ))
data[:maxindex+1] = reversed(data[:maxindex+1])
# Flip it into its final position
if tutor: print('With: %r doflip %i'
% ( ' '.join(str(x) for x in data), size ))
data[:size] = reversed(data[:size])
if tutor: print()
Ruby
class Array
def pancake_sort!
num_flips = 0
(self.size-1).downto(1) do |end_idx|
max = self[0..end_idx].max
max_idx = self[0..end_idx].index(max)
next if max_idx == end_idx
if max_idx > 0
self[0..max_idx] = self[0..max_idx].reverse
p [num_flips += 1, self] if $DEBUG
end
self[0..end_idx] = self[0..end_idx].reverse
p [num_flips += 1, self] if $DEBUG
end
self
end
end
p a = (1..9).to_a.shuffle
p a.pancake_sort!
Swift
import Foundation
struct PancakeSort {
var arr:[Int]
mutating func flip(n:Int) {
for i in 0 ..< (n + 1) / 2 {
swap(&arr[n - i], &arr[i])
}
println("flip(0.. \(n)): \(arr)")
}
func minmax(n:Int) -> [Int] {
var xm = arr[0]
var xM = arr[0]
var posm = 0
var posM = 0
for i in 1..<n {
if (arr[i] < xm) {
xm = arr[i]
posm = i
} else if (arr[i] > xM) {
xM = arr[i]
posM = i
}
}
return [posm, posM]
}
mutating func sort(var n:Int, var dir:Int) {
if n == 0 {
return
}
let mM = minmax(n)
let bestXPos = mM[dir]
let altXPos = mM[1 - dir]
var flipped = false
if bestXPos == n - 1 {
n--
} else if bestXPos == 0 {
flip(n - 1)
n--
} else if altXPos == n - 1 {
dir = 1 - dir
n--
flipped = true
} else {
flip(bestXPos)
}
sort(n, dir: dir)
if flipped {
flip(n)
}
}
}
let arr = [2, 3, 6, 1, 4, 5, 10, 8, 7, 9]
var a = PancakeSort(arr: arr)
a.sort(arr.count, dir: 1)
println(a.arr)
更多代码,敬请期待!
整理自网络