一道关于用C写的洗牌程序
一般的洗牌是先产生一副完整的牌,然后用随机数把牌输出,这种方法很简单,我没有用这种方法,我的思路是这样的:用5个链表(用链表是因为每个接点有两个元素,如果用数组的话好像不方便)前面4个分别保存各种花色的牌,这4个主要是用来记录那些牌有了,那些没有.产生一个牌以后就放到相对应的链表中,放入时还要比较,比较后没有相同的(也就是说是一张新牌)就按产生的顺序放到第5个链表中,这样第5个链表就是按产生顺序随机生成的一副牌.
我的代码如下,有点问题请大家帮忙看一下:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
struct reuslt //用来返回结果
{
int hua;
int num;
}r1,t;
struct pai
{
int hua; //花色
int num; //牌面值
struct pai *next;
};
int Y; //牌是否全部生成 等于0全生成
struct sc
{
char hua1;
int num1;
struct sc *next1;
}*print,*temp;
struct reuslt creat_pai(int Y) //随机创建牌
{
while(Y)
{
r1.hua=rand()%6+3; //产生3-6方便在数据类型转换时不要在变值.
r1.num=rand()%13+1;
return r1;
}
}
int Insert_pai(struct reuslt r1) //把牌插入相应位置
{
struct pai *p1,*q1,*p2,*q2,*p3,*q3,*p4,*q4,*p;
struct pai *head_hei,*head_hong,*head_cao,*head_fang;
int hei,hong,cao,fang; //记录每种花色的牌有多少个
struct sc *pt;
Randomize();
print=(struct sc *)malloc(sizeof(struct sc));
head_hei=(struct pai *)malloc(sizeof(struct pai));
head_hong=(struct pai *)malloc(sizeof(struct pai));
head_cao=(struct pai *)malloc(sizeof(struct pai));
head_fang=(struct pai *)malloc(sizeof(struct pai));
// q1=(struct pai *)malloc(sizeof(struct pai)); //申请空间给它赋初值,方便后面比较.
// q2=(struct pai *)malloc(sizeof(struct pai));
// q3=(struct pai *)malloc(sizeof(struct pai));
// q4=(struct pai *)malloc(sizeof(struct pai));
head_hei-> next=NULL;
head_hong-> next=NULL;
head_cao-> next=NULL;
head_fang-> next=NULL;
print-> next1=NULL;
pt=print;
switch(r1.hua)
{
case 3:
if(head_hei==NULL)
{
p=(struct pai *)malloc(sizeof(struct pai));
p-> hua=r1-> hua; //这里有这个错误:invalid type argument of '-> '
p-> num=r1-> num; //这里有这个错误:invalid type argument of '-> '
head_hei-> next=p;
head_hei=q1;
head_hei-> next=p1;
p-> next=NULL;
}
else
{
while(hei <14)
{
if(p-> num==p1-> num)
break;
else
{
if(p-> num <p1-> num) //第一次就找到插入位置
{
p-> next=p1; //插入
q1-> next=p;
head_hei=q1; //还原指针的位置,以便下次比较
head_hei-> next=p1;
hei=hei+1; //记录加1
break;
}
else
{
if(p1-> next==NULL)
{
p1-> next=p;
head_hei=q1; //还原指针的位置,以便下次比较
head_hei-> next=p1;
hei=hei+1; //记录加1
break;
}
else
{
q1=p1;
p1=p1-> next;
}
}
}
}
//写到输出链表当中去.
temp-> hua1=(char)p-> hua;
temp-> num1=p-> num;
pt-> next1=temp;
pt=temp;
pt-> next1=NULL;
}
break;
//其它的三种情况暂时不写,等一种花色没错了在补上,应该不会有应响
case 4:break;
case 5:break;
case 6:break;
//然后在这个位置写输出链表
}
}
int main(int argc, char *argv[])
{
int i;
for(i=0;i <=i+1;i++)
{
if(Y==0)
break;
t=creat_pai(Y);
Y=Insert_pai(t);
}
system( "PAUSE ");
return 0;
}
//这是那个随机函数.我看了有些的程序不写这个也能生成随机数,这是怎么回事??????
Randomize()
{
srand((unsigned)time(NULL));
}
[解决办法]
//这是那个随机函数.我看了有些的程序不写这个也能生成随机数,这是怎么回事??????
Randomize()
{
srand((unsigned)time(NULL)); //这个安置种子, 使得程序在不同时刻运行得到的随机结果不会重复,如果没有这个语句,那么执行几次程序,得到的结构都是一样的。
}
[解决办法]
你为什么不用简单高效的算法?
关于洗牌算法,一般说对原有有序表元素进行顺序交换形成新的有序表这样的算法应该说是最高效的算法了,而且实现也比较简单的。
你的算法在极限情况下可能不能完成。
[解决办法]
如果要让花色为3-6,
应该是:
r1.hua=rand()%4+3;