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

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

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

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

下面是代码:

#include "stdafx.h"
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>


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;
}

输出结果:


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是使用循环链表解决两数之和问题的C语言代码示例: ```c #include <stdio.h> #include <stdlib.h> // 定义循环链表节点结构体 typedef struct Node { int data; struct Node* next; } Node; // 创建循环链表 Node* createCircularLinkedList(int n) { Node* head = NULL; Node* current = NULL; for (int i = 0; i < n; i++) { // 创建新节点 Node* newNode = (Node*)malloc(sizeof(Node)); if (newNode == NULL) { printf("内存分配失败!"); exit(1); } // 输入节点值 printf("请输入第 %d 个节点的值:", i + 1); scanf("%d", &(newNode->data)); // 将新节点加入链表 if (head == NULL) { head = newNode; current = newNode; } else { current->next = newNode; current = newNode; } } // 将最后一个节点的next指向头节点,形成循环链表 current->next = head; return head; } // 计算两数之和 int sumOfTwoNumbers(Node* head, int num1, int num2) { Node* temp = head; int sum = 0; // 遍历链表,查找num1和num2所在的节点,并计算两数之和 do { if (temp->data == num1 || temp->data == num2) { sum += temp->data; } temp = temp->next; } while (temp != head); return sum; } int main() { int n; // 链表节点个数 int num1, num2; // 需要计算的两个数 printf("请输入链表节点个数:"); scanf("%d", &n); Node* head = createCircularLinkedList(n); printf("请输入需要计算的两个数:"); scanf("%d %d", &num1, &num2); int sum = sumOfTwoNumbers(head, num1, num2); printf("两数之和为:%d\n", sum); return 0; } ``` 这段代码中,我们首先定义了循环链表的节点结构体 `Node`,然后通过 `createCircularLinkedList` 函数创建了一个循环链表,并将输入的节点值存储在链表中。接下来,使用 `sumOfTwoNumbers` 函数遍历链表,查找给定的两个数并计算它们的和。最后,将计算结果输出到控制台。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值