洗牌链表

时间:2014-12-13 08:02:00

标签: c++ linked-list shuffle

我有一个带有双向链表的函数。 Head是第一个节点,tail是最后一个节点。有52个节点(卡片组)我试图做的就是执行一个随机播放,好像你用手洗牌一样。因此,你将甲板切成两半,将上半部分的底部卡片放在新的一堆中,将底部的卡片从另一半中取出并放在那个上面。

因此。左半边是1 2 3右半边是4 5 6后洗牌4 1 5 2 6 3

我知道我的错误在指针中,而且他们互相覆盖。我只是不知道如何正确地对这些列表进行排序并将它们逐个拔出并将它们重新组合在一起。

bool Shuffle(deck* &head, deck* &tail, int ShuffleAmnt)

{

deck* temp_tail = nullptr;
deck* temp_head = head;
deck* temp_list = new deck;
for (int i = 1; i < 26; i++)
    temp_head = temp_head->next;

temp_tail = temp_head->next;

temp_tail->previous = nullptr;

temp_head->next = nullptr;


while (head->next != NULL) // get to the bottom of head
    head = head->next;

temp_head->previous = nullptr;
temp_tail->next = nullptr;

for (int i = 1; i < 26; i++)
{
    temp_list->next = temp_head;
    temp_head = head->previous;
    temp_list = temp_list->next;
    temp_list->next = temp_tail;
}

head = temp_list;



return(true);

}

2 个答案:

答案 0 :(得分:2)

这个答案可能不会直接回答这个问题,但是如果需要的话,它可以指导和教育。

c ++标准库已经具有(几乎) 每个容器类型和逻辑操作的模板实现 。这些构建模块每天都在数十亿计算机中使用,已经针对编译器进行了优化,并且已经由世界上最专业的程序员中的每一位进行了同行评审。简而言之,没有理由考虑编写链表(std::list)或编写随机算法(std::random_shuffle)。

如果你确实想要将卡片保存在链表中(你没有,矢量更自然)你可以重构:

#include <vector>
#include <list>
#include <algorithm>

struct Card {};

typedef std::list<Card> deck; // that's it - a complete linked list implementation

void shuffle_deck(deck& the_deck) {
    // c++11 takes advantage of efficiently copying by value.
    std::vector<Card> temp(std::make_move_iterator(the_deck.begin()),
                           std::make_move_iterator(the_deck.end()));

    // clear out the zombie objects that will have been left by the move
    the_deck.clear();

    // those clever fellows in the standards committee thought of everything...
    // even shuffling a deck of cards!
    std::random_shuffle(temp.begin(), temp.end());

    // move the cards back into the linked list in the correct order
    std::move(temp.begin(), temp.end(), back_inserter(the_deck));
}

如果您决定做正确的事(tm)并使您的牌组成为矢量,那就更简单了:

typedef std::vector<Card> deck_of_cards;

void shuffle_deck(deck_of_cards& deck)
{
    std::random_shuffle(deck.begin(), deck.end());
}

如果你期待写一个有用的职业写c ++,花点时间彻底学习标准库 - 许多c ++程序员都懒得学习algorithm库 - 这是一个错误。它是优雅,可维护代码的基础。

以下是std::random_shuffle文档的链接。 http://en.cppreference.com/w/cpp/algorithm/random_shuffle

你会注意到它被标记为从c ++ 17标准中删除,因为它被上级std::shuffle取代。但是,出于本次讨论的目的,我觉得这可能会让您分心 - 这是为了鼓励您学习和使用标准库: - )

答案 1 :(得分:0)

你可以这样做:

bool Shuffle(deck* &head, deck* &tail, int ShuffleAmnt = 1)
{
  deck* temp_tail = nullptr;
  deck* temp_head = head;
  for (int i = 1; i < 26; i++)
    temp_head = temp_head->next;

  temp_tail = temp_head->next;
  temp_tail->previous = nullptr;

  temp_head->next = nullptr;
  temp_head = head;

  temp_head_next = temp_head->next;
  temp_head_next->previous = temp_head;

  temp_tail_next->next = temp_tail->next;
  temp_tail_next->previous = temp_tail;

  head = temp_tail;

  for (int i = 1; i < 26; i++)
 {
    temp_tail->next = temp_head; 
    temp_head->previous = temp_tail;
    temp_head->next = temp_tail->next;

    temp_tail = temp_head_next;
    temp_head = temp_head_next;

    temp_head_next = temp_head->next;
    temp_head_next->previous = temp_head;

    temp_tail_next->next = temp_tail->next;
    temp_tail_next->previous = temp_tail;
  }
tail = temp_head;
return(true);

}