主题:数据结构课程设计题目(要求用C语言实现)
ypd123
[专家分:0] 发布于 2005-01-04 15:47:00
1)Josephu 问题
Josephu 问题为:设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。
提示:用一个不带头结点的循环链表来处理Josephu 问题:先构成一个有n个结点的单循环链表,然后由k结点起从1开始计数,计到m时,对应结点从链表中删除,然后再从被删除结点的下一个结点又从1开始计数,直到最后一个结点从链表中删除算法结束。
2)疏矩阵的操作
基本功能要求:
稀疏矩阵采用三元组表示,求两个具有相同行列数的稀疏矩阵A和B的相加矩阵C,并输出C。
(2)求出A的转置矩阵D,输出D。
3)背包问题的求解:
假设有一个能装入总体积为T的背包和n件体积分别为w1 , w2 , … , wn 的物品,能否从n件物品中挑选若干件恰好装满背包,即使w1 +w2 + … + wn=T,要求找出所有满足上述条件的解。例如:当T=10,各件物品的体积{1,8,4,3,5,2}时,可找到下列4组解:(1,4,3,2)
(1,4,5)
(8,2)
(3,5,2)。
提示:可利用回溯法的设计思想来解决背包问题。首先将物品排成一列,然后顺序选取物品装入背包,假设已选取了前i 件物品之后背包还没有装满,则继续选取第i+1件物品,若该件物品"太大"不能装入,则弃之而继续选取下一件,直至背包装满为止。但如果在剩余的物品中找不到合适的物品以填满背包,则说明"刚刚"装入背包的那件物品"不合适",应将它取出"弃之一边",继续再从"它之后"的物品中选取,如此重复,,直至求得满足条件的解,或者无解。
由于回溯求解的规则规则是"后进先出"因此自然要用到栈。
4)n皇后问题
问题描述:求出在一个n×n的棋盘上,放置n个不能互相捕捉的国际象棋"皇后"的所有布局
请大家帮忙!
回复列表 (共11个回复)
沙发
LO几又VE [专家分:14490] 发布于 2005-01-04 18:07:00
八皇后问题的非递归实现
http://www.yesky.com/20010324/166508.shtml
N皇后问题
http://www.bashu.com.cn/olympic/standard/dfs/dfs01.htm
N皇后问题算法的实现源码
http://www.vchome.net/tech/datastruct/datasf7.htm
经典8皇后问题
http://www.programfan.com/club/showbbs.asp?id=46870
八皇后问题的高效解法-递归版
http://www.chinaai.org/Article_Show.asp?ArticleID=234
板凳
tomorrowshowyang [专家分:1490] 发布于 2005-01-09 17:44:00
疏矩阵的操作
基本功能要求:
稀疏矩阵采用三元组表示,求两个具有相同行列数的稀疏矩阵A和B的相加矩阵C,并输出C。
求出A的转置矩阵D,输出D:
#include<stdio.h>
int a[10][3]={{3,4,5},{1,2,3},{1,3,1},{2,1,1},{3,2,2},{3,4,1}}'
int b[10][3];
int i,j,q,col,p;
main()
{ b[0][0]=a[0][1];
b[0][1]=a[0][0];
b[0][2]=a[0][2];
if(b[0][2]!=0)
{q=1;
for(col=1;col<=a[0][1];col++)
for(p=1;p<=a[0][2];p++)
if(a[p][1]==col)
{b[q][1]=a[p][0];
b[q][0]=a[p][1];
b[q][2]=a[p][2];
q++;
}}
printf("\n\n output data:\n");
for(i=0;i<=b[0][2];i++)
{for(j=0;j<=2;j++)
printf(" %d",b[i][j]);
printf("\n");}
}
3 楼
tomorrowshowyang [专家分:1490] 发布于 2005-01-09 21:57:00
八皇后问题:
int i,j,k,sum=0;
int safe;
int x[8];
main()
{i=0;j=-1;
while(j<7)&&(!safe))
{j=j+1;k=0;
while((k<i)&&(j!=x[k])&&(i+j!=k+x[k])&&(i-j!=k-x[k]))
k=k+1;
if(i==k)
safe=1;}
if(save)
{x[i]=j;
if(i==7)
{for(i=0;i<=7;i++)
printf("(%d,%d)",i,x[i]);
printf("\n");
sum++;}
else
{i=i+1;j=-1;};
}
else
{i=i-1;
if(i>=0)
j=x[i];}
}
printf("sum=%d",sum);
}
4 楼
eagleflying [专家分:0] 发布于 2005-04-18 22:36:00
josephu问题的循环循环链表实现:
本人做的作业(感觉还好使):
/*约瑟夫(Josephu)问题,用循环链表实现*/
/*如果要求链表的头指针随着链表的更新而依然存在,那么必须在@位置插入如下一段*/
/* if(p==Head) Head=s; */
/*when p is the mth number ,the number before p should be sent to head*/
/*********************************start*************************************/
#include "stdio.h"
#define Len sizeof(struct Josephu)
struct Josephu{
int data;
struct Josephu *next;
}
main()
{
int i,l,m,n=8; /*n为总的人数,m为所报的数,l为开始报数的位置*/
struct Josephu *Head,*p,*s,*L; /*L为每次报数的开始位置*/
/*---------------------———————————————*/
/* 创建一个循环链表 */
/*---------------------------------------------------*/
Head=NULL;
p=Head;
s=(struct Josephu*)malloc(Len);
for(i=1;i<=n;i++)
{
s->data=i;
if(Head==NULL) Head=s;
else p->next=s;
p=s;
s=(struct Josephu*)malloc(Len);
}
p->next=Head; /*使得链表的尾节点指向头指针,从而构成循环链表*/
s=p; /*记下尾节点,当m=1并且l=1时,方便进行序列的更新操作(s->next=L->next;)*/
/*---------------------———————————————*/
/* 解决Josephu问题 */
/*---------------------------------------------------*/
/*输出链表中原来的序列,以便与新序列进行比较*/
printf("The primary sequence is:\n");
p=Head;
while(p->next!=Head)
{
printf("%d\t",p->data);
p=p->next;
}
printf("%d\n",p->data);
/*输入报数的个数和起始位置*/
printf("Input the length and the start place: m (integer and <32767) and l (l<%d)\nm:",n);
scanf("%d",&m);
printf("l:");
scanf("%d",&l);
while(l>n)
{
printf("l is bigger than the maxsize of array Input it again:\nl:");
scanf("%d",&l);
}
/*找到报数的初始位置*/
p=Head;
while(p!=p->next)
{
if(p->data==l)
break;
s=p; /*记下L之前的节点,当m=1,即报到的数为L所指向的数时,方便进行序列的更新操作(s->next=L->next;)*/
p=p->next; /*here:p=L,it is the start place!*/
}
/*找出报到m的元素,并且输出新的序列,这里的s指向所报到m的数之前的元素,从而方便进行序列的更新操作*/
printf("The new sequence is:\n");
while(p!=p->next) /*当发现循环链表只剩下一个元素时,退出循环报数*/
{
for(i=1;i<m;i++)
{
s=p;
p=p->next;
}
/*@请看头部,这里不影响程序的输出结果*/
/*记下指向报到m的数之后的数的指针,并把它作为下一次报数的起始位置*/
L=p->next;
printf("%d\t",p->data);
/*删除刚报过m的数,从而进行序列的更新*/
s->next=L;
/*用p记录下一个报数的初始位置,从而进入下一轮报数*/
p=L;
}
printf("%d\n",p->data);
}
5 楼
eagleflying [专家分:0] 发布于 2005-04-18 22:41:00
这里是用向量结构存储的(感觉有点烂,仅仅交流用,其实可以改成用标记法,不改变数组的长度实现,从而避免当数据的长度很大的时候,更新数组而影响执行的效率):
#include "stdio.h"
void main()
{
int m,l,n=8; /*n为总的人数,m为所报的数,l为开始报数的位置*/
int k,km,t,p; /*k为循环标志,km为n/m取整,l为n除以m的余数,p为移位更新指针*/
int a[9]={0,1,2,3,4,5,6,7,8};
/*提示输出原来的序列,以便与新的序列进行比较*/
printf("The primary array is:\n");
for(k=1;k<=8;k++)
{
printf("%d ",a[k]);
}
printf("\n");
/*输入要报的数和起始位置(即取得m和l的值)*/
printf("Input the longth and the start place: m (integer and <32767) and l (l<%d)\nm:",n);
scanf("%d",&m);
printf("l:");
scanf("%d",&l);
while(l>n)
{
printf("l is bigger than the maxsize of array Input it again:\nl:");
scanf("%d",&l);
}
/*求出经过“josephu变换”后的新的序列并输出显示*/
printf("The new array is:\n");
while(n-1)
{
km=(n-l+1)/m;
t=n-l+1-km*m;
/*输出n以内所有报到m的数*/
for(k=1;k<=km;k++)
printf("%d\t",a[k*m+l-1]);
/*更新序列,即删除已经报数的元素,从最后一个开始更新*/
for(k=km;k>=1;k--)
{
for(p=k*m+l-1;p<n;p++)
a[p]=a[p+1];
n=n-1;
/*当m=1时,上面的过程使得n=0;这里强制n=1, 从而使得当m=1时可以正常的退出循环*/
if(n==0)
n=1;
}
/*判断余数是否为零,即上面的报数是否报到了元素的最后一个*/
/*如果为零,那么下一个开始报数的位置应该回到序列的开头*/
/*否则按下列要求求出下一个开始报数的位置*/
if(t!=0)
{
km=(m-t-1)/n;
l=m-t-km*n;
printf("%d\t",a[l]);
for(p=l;p<n;p++)
a[p]=a[p+1];
n=n-1;
}
else l=1;
}
/*当m!=1的时候,输出最后一个数,否则不再输出*/
if(m!=1)
printf("%d",a[1]);
printf("\n");
}
如果大家有什么好的做法,希望提供交流哦!
6 楼
eagleflying [专家分:0] 发布于 2005-04-19 11:37:00
这里是今天刚改写的用标记法实现的数组解决josephu问题
仅仅改变了一下下面的实现部分(turboc 2 下调试通过)
/*约瑟夫(Josephu)问题,用数组实现(数组从X[1]开始存储)*/
/*********************************start*************************************/
#include "stdio.h"
void main()
{
int m,l,n=8; /*n为总的人数,m为所报的数,l为开始报数的位置*/
int k,t,p; /*p为寻找指针,t为总人数内的报数个数标记,k为共范围内移动指针*/
int a[9]={0,1,2,3,4,5,6,7,8};
int j=n; /*j为循环退出标记,当j=0时候说明执行完毕*/
/*提示输出原来的序列,以便与新的序列进行比较*/
printf("The primary array is:\n");
for(k=1;k<=8;k++)
{
printf("%d ",a[k]);
}
printf("\n");
/*输入要报的数和起始位置(即取得m和l的值)*/
printf("Input the longth and the start place: m (integer and <32767) and l (l<%d)\nm:",n);
scanf("%d",&m);
printf("l:");
scanf("%d",&l);
while(l>n)
{
printf("l is bigger than the maxsize of array Input it again:\nl:");
scanf("%d",&l);
}
[color=008000]
/*求出经过“josephu变换”后的新的序列并输出显示*/
p=t=0;
for(k=l;k<=n;k++)
{
if(a[k]!=0) p++;
if(p==m)
{
printf("%d\t",a[k]);
t++; j--;
a[k]=0;
if(l==n+1) { k=0;t=0;}
p=0;
}
if(k==n&&p<m) { k=0; t=0;}
if(j==0) break;
}
}[/color]
7 楼
flyyee [专家分:30] 发布于 2005-05-09 19:38:00
Josephu 问题
#include <stdio.h>
#include <malloc.h>
#define OK 1
#define ERROR -1
#define OVERFLOW -2
typedef int Status;
typedef struct LNode{//定义结点
int num;
int key;
struct LNode *next;
}LNode,Joseph;
Status Input_Num(Joseph *p,int i){//输入各结点编号
p->num=i;
return OK;
}//Input_Num
Status Input_Key(Joseph *p){//输入各结点密码
printf("请输入第%d个人的密码:",p->num);
scanf("%d",&p->key);
while(!p->num){
printf("输入有误,请重新输入:");
scanf("%d",p->key);
}//while
return OK;
}//Input_Key
Status Print_Num(Joseph *h){//输出号码
printf("%d ",h->num);
return OK;
}//Get_Num
Status Get_Key(Joseph *h,int &Key){//为Key赋值
Key=h->key;
return OK;
}//Get_Key
Joseph *Create_Node(void){//创建新结点
Joseph *p;
do{
p=(Joseph *)malloc(sizeof(Joseph));
}while(!p);
return p;
}//Create_Node
Status Search_Node(Joseph *&p,Joseph *&h,int Key){//查找结点
if(Key==1)
return OK;
else{
int i;
for(i=2;i<=Key;i++){
p=h;//p指向待查结点的前继
h=h->next;
}//for
return OK;
}//else
}//Search_Node
Status Delete_Node(Joseph *p,Joseph *&h){//删除结点
Joseph *q=h;
if(h!=h->next){
h=h->next;
p->next=h;
}
else
p=h=NULL;
free(q);
return OK;
}//Delete_Node
Joseph *CreateList_CL(void){//构造循环链表
Joseph *p,*q,*h;
int i=1,n;
printf("请输入人数:");
scanf("%d",&n);
while(n<=0){//若输入不是正数
printf("输入有误,请重新输入:");
scanf("%d",&n);
}//while
h=q=p=Create_Node();
Input_Num(p,i);Input_Key(p);//创建第一个结点
for(i=2;i<=n;i++){
p=Create_Node();
Input_Num(p,i);
Input_Key(p);
q->next=p;//q指向p的前继
q=p;
}//for
q->next=h;//连接成循环链表
return h;
}//CreateList_CL
Status Joseph_Circle(Joseph *h){
int Key;
Joseph *p=h;
printf("请输入初始密码:");
scanf("%d",&Key);//为Key赋初值
if(Key==1)
while(p->next!=h)
p=p->next;
while(h->next!=h){ //(1)
//当未出列人数多于一人时
//h指向要查找的结点
Search_Node(p,h,Key);//p指向待查结点的前继
Print_Num(h);//打印出列人的编号
Get_Key(h,Key);//换用出列人的密码
Delete_Node(p,h);
}//(1)
Print_Num(h);//打印最后未出列人的编号
Delete_Node(p,h);
return OK;
}//Joseph
void main(){
Joseph_Circle(CreateList_CL());
}//main
8 楼
hbbdgxh [专家分:0] 发布于 2005-05-10 10:33:00
八皇后
#include "stdio.h"
int a[8],b[24],c[24],d[24];
int i, k,t=0;
void print()
{
t++;
printf(" %d",t);
for (k=0;k<8;k++)
printf(" %d",a[k]);
printf("\n");
}
void try(int i)
{
int j;
for (j=0;j<8;j++)
{/*每个皇后都有8种可能位置*/
if ((b[j]==0) &&(c[i+j]==0)&& (d[i-j]==0))/*判断位置是否冲突*/
{
a[i]=j;/*摆放皇后*/
b[j]=1;/*宣布占领第J行*/
c[i+j]=1; /*占领两个对角线*/
d[i-j]=1;
if (i<8)
try(i+1);/*8个皇后没有摆完,递归摆放下一皇后*/
else
print();/*完成任务,打印结果*/
b[j]=0; /*回溯*/
c[i+j]=0;
d[i-j]=0;
}
}
}
void main()
{
for( k=0;k<24;k++)
{/*数据初始化*/
b[k]=0;
c[k]=0;
d[k]=0;
}
try(1);/*从第1个皇后开始放置*/
}
9 楼
hbbdgxh [专家分:0] 发布于 2005-05-10 10:35:00
稀疏矩阵建立
#include "stdio.h"
#define MAX_SIZE 50 /* 最大的稀疏矩阵 */
typedef enum {head, entry} tagfield;
struct entry_node {
int row;
int col;
int value;
};
typedef struct Matrix {
struct Matrix * down;
struct Matrix * right;
tagfield tag;
union {
struct Matrix * next;
struct entry_node entry;
} u;
}matrix_node;
typedef matrix_node * matrix_pointer;
matrix_pointer hdnode [ MAX_SIZE ];
matrix_pointer new_node(void)
{
matrix_pointer temp;
temp = (matrix_pointer)malloc(sizeof(matrix_node));
if (temp==NULL) {
printf("The memory is full\n");
exit(1);
}
return temp;
}
matrix_pointer Create(void)
{
int num_rows, num_cols, num_terms, num_heads, i,current_row;
int col, value,row;
matrix_pointer node,temp,last;
printf("Enter the number of rows, columns and number of nonzero terms: ");
scanf("%d%d%d",&num_rows,&num_cols,&num_terms);
num_heads = (num_cols > num_rows) ? num_cols :num_rows;
/* 建立新结点 */
node = new_node();
node->tag = entry;
node->u.entry.row = num_rows;
node->u.entry.col = num_cols;
if ( !num_heads )
node->right = node;
else { /*初始化头结点如图5-5-4*/
for ( i = 0; i<num_heads; i++ ) {
temp = new_node();
hdnode[i] = temp;
hdnode[i]->tag = head;
hdnode[i]->right = temp;
hdnode[i]->u.next = temp;
}
current_row = 0;
last = hdnode[0];
for ( i = 0; i < num_terms; i++ ) {
printf("Enter row, column and value: ");
scanf("%d%d%d",&row,&col,&value);
if ( row > current_row ) {
/* 转到row所在行去*/
last->right = hdnode[current_row];
current_row = row;
last = hdnode[row];
}
temp = new_node();
temp->tag = entry;
temp->u.entry.row = row;
temp->u.entry.col = col;
temp->u.entry.value = value;
/* 链接到行结点上如图5-5-5所示 */
last->right = temp;
last = temp;
/*链接到列结点上 */
hdnode[col]->u.next->down = temp;
hdnode[col]->u.next = temp;
}
/* 结束上一行结点 */
last->right = hdnode[current_row];
/*结束所有行结点*/
for ( i=0; i<num_cols; i++ )
hdnode[i]->u.next->down= hdnode[i];
/*链接所有的头结点 */
for ( i=0; i<num_heads-1; i++ )
hdnode[i]->u.next = hdnode[i+1];
hdnode[num_heads-1]->u.next = node;
node->right = hdnode[0];
}
return node;
}
void main()
{
matrix_pointer matric=Create();
}
稀疏矩阵删除
#include "stdio.h"
#define MAX_SIZE 50 /* 最大的稀疏矩阵 */
typedef enum {head, entry} tagfield;
struct entry_node {
int row;
int col;
int value;
};
typedef struct Matrix {
struct Matrix * down;
struct Matrix * right;
tagfield tag;
union {
struct Matrix * next;
struct entry_node entry;
} u;
}matrix_node;
typedef matrix_node * matrix_pointer;
matrix_pointer hdnode [ MAX_SIZE ];
matrix_pointer new_node(void)
{
matrix_pointer temp;
temp = (matrix_pointer)malloc(sizeof(matrix_node));
if (temp==NULL) {
printf("The memory is full\n");
exit(1);
}
return temp;
}
matrix_pointer Create(void)
{
int num_rows, num_cols, num_terms, num_heads, i,current_row;
int col, value,row;
matrix_pointer node,temp,last;
printf("Enter the number of rows, columns and number of nonzero terms: ");
scanf("%d%d%d",&num_rows,&num_cols,&num_terms);
num_heads = (num_cols > num_rows) ? num_cols :num_rows;
/* 建立新结点 */
node = new_node();
node->tag = entry;
node->u.entry.row = num_rows;
node->u.entry.col = num_cols;
if ( !num_heads )
node->right = node;
else { /*初始化头结点如图5-5-4*/
for ( i = 0; i<num_heads; i++ ) {
temp = new_node();
hdnode[i] = temp;
hdnode[i]->tag = head;
hdnode[i]->right = temp;
hdnode[i]->u.next = temp;
}
current_row = 0;
last = hdnode[0];
for ( i = 0; i < num_terms; i++ ) {
printf("Enter row, column and value: ");
scanf("%d%d%d",&row,&col,&value);
if ( row > current_row ) {
/* 转到row所在行去*/
last->right = hdnode[current_row];
current_row = row;
last = hdnode[row];
}
temp = new_node();
temp->tag = entry;
temp->u.entry.row = row;
temp->u.entry.col = col;
temp->u.entry.value = value;
/* 链接到行结点上如图5-5-5所示 */
last->right = temp;
last = temp;
/*链接到列结点上 */
hdnode[col]->u.next->down = temp;
hdnode[col]->u.next = temp;
}
/* 结束上一行结点 */
last->right = hdnode[current_row];
/*结束所有行结点*/
for ( i=0; i<num_cols; i++ )
hdnode[i]->u.next->down= hdnode[i];
/*链接所有的头结点 */
for ( i=0; i<num_heads-1; i++ )
hdnode[i]->u.next = hdnode[i+1];
hdnode[num_heads-1]->u.next = node;
node->right = hdnode[0];
}
return node;
}
void erase(matrix_pointer *node)
{
matrix_pointer x,y,head = (*node)->right;
int i;
/* 遍历每行,删除元素结点和头结点 */
for ( i = 0; i< (*node)->u.entry.row; i++ ) {
y = head->right;
while ( y != head ) {
x = y; y = y->right;
free(x);
}
x = head; head = head->u.next; free(x);
}
/* 删除剩余的头结点*/
y = head;
while ( y != *node ) {
x = y;
y = y->u.next;
free(x);
}
free(*node);
*node = NULL;
}
void main()
{
matrix_pointer matric=Create();
erase(&matric);
}
10 楼
sss2478 [专家分:0] 发布于 2007-06-28 09:15:00
飞机定票系统模拟 c语言编程实现谁会啊,谢谢大家帮个忙啊 我的油箱lzhlg2478@126.com
我来回复