排序算法——煎饼排序(Pancake sort)【代码实现】

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)

更多代码,敬请期待!
整理自网络

发布了56 篇原创文章 · 获赞 166 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_36721220/article/details/92015139