出列排序 《算法》2.1.14

来源:互联网 发布:软件开发风险管理 编辑:程序博客网 时间:2024/04/28 18:13

Sedgewick 算法第四版

2.1.14题:出列排序

“说说你会如何将一副扑克牌排序,限制条件是只能查看最上面的两张牌,交换最上面的两张牌,或是将最上面的一张牌放到这摞牌的最下面。”



思路一:类似select sort,每过一轮找到一张最大(小)的,放到最后。下一轮再找一张最大(小)的,等到合适的位置将其放到上一轮的牌的后面


思路二:类似insert sort,只是方向有所不同。insert sort的向prev方向insert的过程在这里表现为顺序过牌并交换;insert sort的下一轮迭代,now_place向next方向移动一位的过程在这里表现为纸牌过了一轮减1张牌


思路三:由思路二抽象想到。本题的元操作可以组合出,swap操作,next/prev操作,等操作。将现有的各种排序算法的操作转换为本题的操作即可完成



exercise2.1.14.h

#pragma once#include <iostream>//习题2.1.14//出列排序//“说说你会如何将一副扑克牌排序,限制条件是只能查看最上面的两张牌,交换最上面的两张牌,或是将最上面的一张牌放到这摞牌的最下面。”class cards {public://题目所给操作int first();//查看第一张int second();//查看第二张void swap();//交换第一张和第二张void first_go_down();//将第一张放到最下面//其它操作cards();//构造出一副从小到大排列好的牌void show();//从头到尾打印出当前牌堆void shuffle();//洗牌        ~cards();private:        int* card;//牌堆数组,设有52张(4 x 13 张)牌};//selectsort式void card_sort_V1(cards& c);//insertsort式void card_sort_V2(cards& c);
exercise2.1.14.cpp

#include "exercise2.1.14.h"#include <random>#include <ctime>int cards::first(){return card[0];}int cards::second(){return card[1];}void cards::swap(){using std::swap;swap(card[0], card[1]);}void cards::first_go_down(){int tmp = card[0];for (int i = 0; i < 51; ++i) {card[i] = card[i + 1];}card[51] = tmp;}cards::cards() :card(new int[52]){for (int i = 0; i < 52; ++i) {card[i] = i / 4 + 1;}}cards::~cards(){delete[] card;}void cards::show(){for (int i = 0; i < 52; ++i) {std::cout << card[i] << " ";}}void cards::shuffle(){using std::swap;static std::default_random_engine rgen(time(nullptr));static std::uniform_int_distribution<> dist;for (int i = 0; i < 52; ++i) {swap(card[i], card[dist(rgen, std::uniform_int<int>::param_type(0, i))]);}}//selectsort式void card_sort_V1(cards & c){c.show();//共计52轮for (int i = 0; i<52; ++i) {//得出本轮的最小者for (int j = i; j<51; ++j) {if (c.first() < c.second()) {c.swap();//将小的暂存在second}c.first_go_down();//将大的pass}//将本轮最小的放在上一轮最小的之后,开始下一轮for (int k = i; k > 0; --k) {c.swap();c.first_go_down();}c.first_go_down();}//排序完毕c.show();}//insertsort式void card_sort_V2(cards & c){c.show();//52次insert to proper placefor (int i = 0; i < 52; ++i) {//insert to proper placeint j;for (j = 0; j < i; ++j) {//在本轮范围之内if (c.first() > c.second()) {c.swap();//将大的向下移动至合适的位置c.first_go_down();//将小的passcontinue;}break;}for (int k = j; k < 51; ++k) {c.first_go_down();//本轮排序完毕,将位置排列好,置于下轮开始状态}}//最后差一次c.first_go_down();c.show();}


0 0
原创粉丝点击