循环链表解决魔术师发牌问题和拉丁方阵

这是小甲鱼数据结构视频中的两题,主要用的数据结构是循环链表。。

魔术师发牌问题:有13张同样花色的牌按照一定顺序摆放,然后按照公差为1的等差数列逐次取出,在求要取出的牌的过程中未取出的牌将顺次加入到末尾,求出能够达成这样效果的牌序.

拉丁方阵问题,用N个不同数字排除N * N的方阵使之行和列的数字都不一样.

下面是代码:

#include "stdafx.h"
#include 
#include 
#include 


typedef int Elemtype;

typedef struct Node {
	Elemtype data;
	struct Node *next;
}List,*NodeList;

//构建循环链表//
NodeList Create_List(int CardNum) {
	NodeList PHead = (Node *)malloc(sizeof(Node));
	NodeList S,P;     //动态创建结点
	S = (Node *)malloc(sizeof(Node));//创建第一个结点
	S->data = 0;
	S->next = NULL;
	PHead->next = S;//头结点指向第一个结点
	P = S;
	for (int i = 1; i < CardNum; i++) {
		//创建剩下的CardNum-1个结点
		S = (Node *)malloc(sizeof(Node));
		S->data = 0;
		S->next = NULL;
		P->next = S;
		P = S;
	}
	//退出循环的时候P,S指向最后一个结点
	P->next = PHead->next;
	free(PHead);
	return P->next;  //返回第一个结点
}

//遍历循环链表//
void Traverse(NodeList P) {
	int count = 1;
	NodeList P1 = P;
	printf("NO.%d->%d\t", count, P1->data);
	count++;
	while (P1->next != P) {
		P1 = P1->next;
		printf("NO.%d->%d\t", count, P1->data);
		count++;
	}
	//当退出循环的时候,P1指向最后一个结点
	printf("\n");
}

//魔术师发牌问题解法//
void Magical_Card(NodeList P,int CardNum) {
	//算法是按照等差数列递增的方法进行计数
	//当到达的结点值为0的时候则跳过,重新计数
	//也就是说要在所有为0的结点处进行牌的放置
	int count = 1;
	P->data = count;   //头结点赋值为1
	count++;
	while (1) {
		for (int i = 0; i < count; i++) {
			//往后逐渐计数
			P = P->next;
			if (P->data != 0)
				//此时表示这个位置已经放置过牌了
				//也就是在表演魔术的时候已经把牌拿出去了
				i--;  //表示要重新计数
		}
		//退出循环之后P指向要填入数字的结点
		P->data = count;
		count++;
		if (count == CardNum+1)
			break;//退出条件就是13个数字全部填入了
	}
}

//拉丁方阵问题解法//
void Latin_Matrix(NodeList P,int CardNum) {
	//拉丁方阵实际上要指定两个指针,进行循环嵌套
	//输出过一遍之后就进行换行
	int i, j;
	printf("拉丁方阵为:\n");
	NodeList P1;   //用来记录每行开始循环的位置
	P1 = P;        //第一行就是从第一个结点开始打印
	for (i = 0; i < CardNum; i++) {
		printf("%d\t", P->data);
		P = P->next;
	}
	printf("\n");
	for (i = 1; i < CardNum;i++) {
		P1 = P1->next;
		P = P1;    //接下来每一次循环P1都会向后一位,P从P1位置开始
		for (j = 0; j < CardNum; j++) {
			printf("%d\t", P->data);
			P = P->next;
		}
		printf("\n");
	}
}

int main()
{
	NodeList P;
	P = Create_List(5);
	Magical_Card(P,5);
	Traverse(P);
	Latin_Matrix(P,5);
    return 0;
}

输出结果:

循环链表解决魔术师发牌问题和拉丁方阵_第1张图片

你可能感兴趣的:(数据结构)