Sorting a deque using limited operations?

若如初见. 提交于 2019-12-01 04:03:26

问题


Hi I came across a question in the Algorithms 4th Edition by Robert Sedgewick.

Dequeue sort. Explain how you would sort a deck of cards, with the restriction that the only allowed operations are to look at the values of the top two cards, to exchange the top two cards, and to move the top card to the bottom of the deck.

I was hoping someone could explain how this would be done, I am really lost. Thanks you


回答1:


Rather than thinking of the deck having a top and a bottom, imagine that the deck of cards is arranged in a ring. You can imagine having a marker that you place between two specific cards, which then corresponds to the top of the deck. Your operations of "swap the top two cards" is then swapping the two cards to the left of the marker, and the operation of "move the top of the deck to the bottom" then corresponds to moving the marker one step to the left.

Given this, you can naturally adapt bubble sort to work in this setup. Permanently mark one of the positions in the ring as the start point. Then, repeatedly do the following: if the two cards to the left of the marker are out of order, swap them. Then, move the marker one step to the left. As an exception to the rule, if the marker is one step before the marker's initial position, don't do the comparison. If you go around the circle without exchanging anything, you're done!

In pseudocode, this would look as follows:

repeat the following until no swaps are made:
    counting from i = 1 to n - 1, inclusive:
       if the top two cards are out of order, swap them.
       move the top card of the deck to the bottom.
    then, move the top card of the deck to the bottom.

Hope this helps!




回答2:


A very simple solution is here using java. Just keep shifting the top element by comparing and keep track of the number of sorted elements. On every iteration, it will give us one smallest element based on the position. We will do this based on n and k values. For n values, we will keep shifting based on bigger elements and for k values, we will just keep shifting based on smaller values and eventually, the solution will come. You can try this.

private void sort(Integer[] a) {
        int n = a.length-1,k=1;
        while (n>0){
            for (int i = 0; i < n; i++) {
                if (a[1]>a[0]){
                    int temp = a[0];
                    a[0] = a[1];
                    a[1] = temp;
                }
                pushToBackAndShift(a);
            }
            for (int i = 0; i < k; i++) {
                if (a[1]<a[0]){
                    int temp = a[0];
                    a[0] = a[1];
                    a[1] = temp;
                }
                pushToBackAndShift(a);
            }
            n--;k++;
        }
        pushToBackAndShift(a);
    }

private void pushToBackAndShift(Integer[] a) {
        int temp = a[0];
        for (int i = 0; i < a.length-1; i++) {
            a[i] = a[i+1];
        }
        a[a.length-1] = temp;
    }



回答3:


I have a strategy which seems very straightforward to myself:

Consier this the same as the bubble sort: 1) compare(possibly swap) and then move; 2) dont' compare and move(don't change the order). And two kinds of actions take 52 steps(the length of the decks) in one round.

Condition 1:

def exchange_move(cards): 
    if cards[0] > cards[1]:
        cards[0], cards[1] = cards[1], cards[0]
        cards.append(cards.popleftL())
    else:    
        cards.append(cards.popleft())

Condition 2:

def move(cards): 
    cards.append(cards.popleft())

And take these two kinds of actions in each round:

for i in range(card_len-skip):
    exchange_move(cards)
for i in range(skip)
    move(cards)

And this is the complete code in Python:

from collections import deque
import random
from enum import Enum

class Suit(Enum):
    __order__ = "spade heart club diamond"
    spade = 1
    heart = 2
    club = 3
    diamond = 4


class Card(object):
    def __init__(self, suit, value):
        assert type(suit) == Suit
        assert value > 0 and value < 14
        self._suit = suit
        self._value = value
        self.value = self._get_value()

    def _get_value(self):
        return self._suit.value * 13 + self._value

    def __lt__(self, other):
        return self.value < other.value

    def __str__(self):
        return str((self._suit.name, self._value))

cards = deque(maxlen=52)

for s in Suit:
    for i in range(13):
        cards.append(Card(s, i+1))

random.shuffle(cards)

def is_sorted(cards):
    for i in range(len(cards)-2):
        if cards[i] > cards[i+1]:
            return False
    return True

def exchange_move(cards):
    if cards[0] > cards[1]:
        cards[0], cards[1] = cards[1], cards[0]
    cards.append(cards.popleft())

def move(cards):
    cards.append(cards.popleft())

skip = 0
while(not is_sorted(cards)):
    if skip == len(cards):
        print('something strange happened')
    for i in range(len(cards)-skip):
        exchange_move(cards)
    for i in range(skip):
        move(cards)
    skip += 1

for c in cards:
    print(c)


来源:https://stackoverflow.com/questions/28243757/sorting-a-deque-using-limited-operations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!