数据结构之循环链表

**

数据结构之循环链表

**

#include<iostream>
#include<string>
#include<stdlib.h>

using namespace std;

/*
有 10 个小朋友按编号顺序 1,2,。。。,10 顺时针方向围成一圈。
从 1 号开 始顺时针方向 1,2,。。。,9 报数,凡报数 9 者出列
(显然,第一个出圈为 编号 9 者)。 最后一个出圈者的编号是多少?
第 5 个出圈者的编号是多少?
*/
typedef struct _LinkNode {
	int data;                //结点的数据域
	struct _LinkNode* next;  //结点的指针域
}LinkNode,LinkList;          //LinkList 为指向结构体 LNode 的指针类型

void LinkPrint(LinkList* L);

bool InitList(LinkList* & L) {//构造一个空的循环链表 L
	L = new LinkNode;         //生成新结点作为头结点,用头指针 L 指向头结点

	if (!L) return false;     //生成结点失败

	L->next = L;//头结点的指针域指向自己
	L->data = -1;
	return true;
}

//尾插法
bool ListInsert_back(LinkList*& L, LinkNode* node) {
	LinkNode* last = NULL;

	if (!L || !node) return  false;
	//找到最后一个结点
	last = L;
	while (last->next != L) last = last->next;

	//新的节点链接到最尾部 
	node->next = L; 
	last->next = node;
	return true;
}

//删除节点
bool Joseph(LinkList*& L, int interval) {

	//在带头节点的循环链表L中,每个interval个间隔循环删除节点
	LinkList* p, * q;
	int j = 0;
	int i = 0;
	int times = 0, num = 0;
	p = L;

	if (!L || p->next == L) {
		cout << "链表为空" << endl;
		return false;
	}

	if (interval < 1) {
		cout << "报数淘汰的口令不能小于1!" << endl;
		return false;
	}
	do {
		i += interval;
		while ((p->next)) { //查找第 i 个结点,p 指向该结点的上一个节点
			if (p->next != L) j++;
			if (j >= i) break;
			p = p->next;
		}
		times++; //圈数加一
		/*if (!(p->next)||(j>i))//当 i>n 或 i<1 时,
		删除位置不合理 return false;*/

		q = p->next;    //临时保存被删节点的地址以备释放空间
		num = q->data;
		if (times == 5) cout << "第 5 个出圈的编号是:" << num << endl;
		printf("cur: %d last: %d next:%d\n", q->data, p->data, q->next->data);

		p->next = q->next;  //改变删除结点前驱结点的指针域

		delete q;   //释放被删节点的空间
		LinkPrint(L);  //打印出剩下节点的表中的各值
	} while (L->next != L);    //链表不为空,可以继续报数

	cout << "最后一个出圈的编号是:" << num << endl;
	return true;
}

//循环链表的输出
void LinkPrint(LinkList* L) {
	LinkList* p;

	if (!L || L == L->next) {
		cout << "链表为空" << endl;
		return;
	}

	p = L->next;
	while (p!= L) {
		cout << p->data << "\t";
		p = p->next;
	}
	cout << endl;
}

int main(void) {
	int i, x;
	LinkList* L;
	LinkNode* s;

	//1.初始化一个空的循环链表
	if (InitList(L)) {
		cout << "初始化一个空的循环链表!\n";
	}

	//2.创建循环链表(尾插法)
	cout << "尾插法创建循环链表,插入10个元素..." << endl;
	i = 0;
	while ((++i) <= 10)
		{
			s = new LinkNode; //生成新的节点
			s->data = i;  //输入元素值赋给新节点的数据域
			s->next = NULL;
			if (ListInsert_back(L, s)) {
				cout << "插入成功" << endl;
			}
			else {
				cout << "插入失败" << endl;
			}
		}

	cout << "尾插法创建循环链表输出结果:\n";
	LinkPrint(L);

	//3.解答约瑟夫问题
	Joseph(L, 9);
	system("pause");
	return 0;
}

运行结果如下:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值