魔术师发牌问题-数据结构和算法

数据结构 专栏收录该内容
46 篇文章 0 订阅
/***************************************************
*CopyRight(C)2016年6月14日14:56:54
*Author:邱于涵
*Blog:博客:http://blog.csdn.net/u012997311
*问题名称:魔术师发牌问题
*问题描述:魔术师手里一共有13张牌,全是黑桃,1~13.
*********魔术师需要实现一个魔术:这是十三张牌全部放在桌面上(正面向下),
********第一次摸出第一张,是1,翻过来放在桌面上。
******第二次摸出从上往下数第二张,是2,翻过来 放在桌面上,(第一张放在最下面去,等会儿再摸),
*****第三次摸出从上往下数第三张,是3,翻过来放在桌面上,(第一张和第二张 放在最下面去,等会儿再摸)
***  以此类推 最后一张就是13
*******************************************************/
#include<iostream>
using namespace std;
/**********************************************************
*数据储存结构:循环链表
**********************************************************/
struct HanNode{
	int data;//牌的内容
	HanNode * nextPtr;//|下一个结点
};
/**********************************************************
*创建循环链表
**********************************************************/
HanNode * create(int amount)
{
	if (amount <= 0)
		return 0;
	if (amount == 1)
	{
		HanNode * Node = new HanNode;
		Node->data = 1;
		Node->nextPtr = Node;
		return Node;
	}
	else{
	
		HanNode * head = new HanNode;
		head->data = 0;//head->data = 1;
		head->nextPtr = head;
		//|上一个结点
		HanNode * preNode = head;
		//|当前结点
		HanNode * nowNode = 0;
		//|计数
		int i = 2;
		while (i <= amount)
		{
			nowNode = new HanNode;
			nowNode->data = 0;//nowNode->data = i;
			//|下一个结点为头结点
			nowNode->nextPtr = head;
			//|插入到上一个结点(尾结点的位置)
			preNode->nextPtr = nowNode;
			//|当前结点为preNode;
			preNode = nowNode;
			//|递增(迭代)
			++i;
		}
		return head;
	}
}
/**********************************************************
*遍历输出(这个主要用于调试)
**********************************************************/
void echoEach(HanNode * p)
{
	HanNode * head = p;
	cout << p->data << endl;
	HanNode * tmp = head->nextPtr;
	while (tmp != head)
	{
		cout << tmp->data << endl;
		//|迭代
		tmp = tmp->nextPtr;
	}
}
/**********************************************************
*魔术师(发牌顺序)
**********************************************************/
void Magician(HanNode * head,int amount)
{

	//amount 为扑克牌数量 其实 这里可以直接 计算数量的为了 算法的空间复杂度就直接代入好了



	//|设置扑克牌顺序



	int i = 1;
	/*************************************************************************
	*需要设置一个临时前缀 类似没有用的 Head头指针
	*用于方便迭代遍历  第一次循环一次 ,第二次循环两次,第三次循环三次
	*如果不这样做的话 就是 第一次循环0次,第二次循环2次,就不好设置
	*****************************************************************************/
	HanNode * tmpprefix = new HanNode;
	tmpprefix->nextPtr = head;
	HanNode * tmp = tmpprefix;
	while (i <= amount)
	{
		for (int j = 0; j < i; j++)
		{
			//|迭代
			tmp = tmp->nextPtr;
			//|如果下一张牌 拿出去了(标上数字了),就需要再循环--j.
			if (tmp->data != 0)
				j = j - 1;
		}
		tmp->data = i;
	    //|迭代
		++i;
	}
	delete tmpprefix;
	//|输出扑克牌顺序

	cout << "扑克牌摆放顺序:";
	tmp = head->nextPtr;
	cout << "黑桃" << head->data<<",";
	while (tmp != head)
	{
		cout << "黑桃" << tmp->data << ",";
		tmp = tmp->nextPtr;
	}
}
/**********************************************************
*销毁函数
**********************************************************/
void destory(HanNode *head)
{
	if (head->nextPtr == head)
	{
		delete head;
	}
	else{
		HanNode * tmp = head->nextPtr;
		while (tmp != head)
		{
			HanNode * tmpdel = tmp;
			tmp = tmp->nextPtr;
			delete tmpdel;
		}
		//|最后释放head
		delete tmp;
	}
}
/**********************************************************
*主函数
**********************************************************/
int main(int argc, char * argv[]){

	HanNode * p = create(13);
	echoEach(p);
	Magician(p, 13);
	destory(p);
	while (1);
	return 1;
}

  • 0
    点赞
  • 0
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值