单向循环链表
无论插入或者删除链表的末尾结点的Next指针永远指向头结点 达到循环的目的,
生活当中那些事物是循环的呢?
一是时间 ,二是一周,三是人的工作,生活 都是循环 …我们发现无法打破, 生活该继续的继续,
唯一的是生活方式发生改变,其他的事物都无任何变化,可能有人离世,可能有人出世,
有人以某种职业干到不能干为止,这些都是属于事物循环
让我们看看单向循环链表的图:
在这个单向循环链表里很清楚的看到 链表的数据域 链接指针域 是个循环的姿态 所以判断是否结束不要判断为nullptr,而是判断某个结点是否跟头结点有一一定的关系
关于单向循环链表 :头部添加,尾部添加 元素 ,在某个位置插入元素 ,在某个位置删除元素 获取某个位置的元素,查找某个位置的结点 这些就简单操作,就没有必要的投入这些细节,如果还不熟悉这些链表的操作
就看这些:
单向链表操作函数:
链表添加元素 web link
链表插入元素 web link
链表删除元素 web link
获取链表元素 web link
查找链表结点 web link
链接链表结点 web link
解除链接结点 web link
本质都是一样的,但是链表的末尾的Next指针域指向头结点
单向循环链表基本操作
函数声明
#ifndef __LOOPLINKLIST_H__
#define __LOOPLINKLIST_H__
//循环链表结点元素类型
using LoopLinkNodeElemType = int;
using ElemType = LoopLinkNodeElemType;
//循环链表结点
using LinkNode = struct __LoopLinkNode;
//循环链表结点
struct __LoopLinkNode {
ElemType value;
LinkNode* next;
};
//循环链表
using LoopLinkList = struct __LoopLinkList;
//循环链表
struct __LoopLinkList {
//链表结点指针指向首结点
LinkNode* list;
//元素个数
size_t size;
};
//初始化循环链表
bool initLoopLinkList(LoopLinkList& List);
//创建首节点
LinkNode* creatorLinkNode(void);
//创建节点并且初始化数据
LinkNode* creatorLinkNode(ElemType const & value);
//循环链表尾部插入
void LoopLinkListInsert_back(LoopLinkList& List, LinkNode*& Newnode);
//循环链表头部插入
void LoopLinkListInsert_froot(LoopLinkList& List, LinkNode*& Newnode);
//链接结点
void Link(LinkNode*& node, LinkNode*& Newnode);
//遍历链表元素
void showLoopLinkList(LoopLinkList& List);
#endif
创建单向循环链表code:
函数实现
#include "LoopLinkList.h"
#include<iostream>
using namespace std;
bool initLoopLinkList(LoopLinkList& List){
List.list = creatorLinkNode();
List.size = 0u;
return true;
}
LinkNode* creatorLinkNode(void){
LinkNode* node = new LinkNode;
node->next = node;
return node;
}
单向循环链表 头部添加元素code:
函数实现
LinkNode* creatorLinkNode(ElemType const& value){
LinkNode* node = new LinkNode;
node->value = value;
node->next = nullptr;
return node;
}
void LoopLinkListInsert_froot(LoopLinkList& List, LinkNode*& Newnode){
Link(List.list, Newnode);
++List.size;
}
单向循环链表 尾部添加元素code:
函数实现
void LoopLinkListInsert_back(LoopLinkList& List, LinkNode*& Newnode){
LinkNode* current = List.list;
while (current->next != List.list) {
current = current->next;
}
Link(current, Newnode);
++List.size;
}
单向循环链表 链接结点操作code:
函数实现
void Link(LinkNode*& node, LinkNode*& Newnode) {
Newnode->next = node->next;
node->next = Newnode;
}
单向循环链表 遍历操作code:
函数实现
void showLoopLinkList(LoopLinkList& List){
for (LinkNode* iter = List.list->next; iter != List.list; iter = iter->next) {
cout << "链表数据元素为:" << iter->value << "\t";
}
cout << endl;
}
学会了基本操作后,来看看约瑟夫问题吧
单向循环链表-约瑟夫问题
有 10 个小朋友按编号顺序 1,2,。。。,10 顺时针方向围成一圈。从 1 号开 始顺时针方向 1,2,。。。,9 报数,凡报数 9 者出列(显然,第一个出圈为 编号 9 者)。 最后一个出圈者的编号是多少?第 5 个出圈者的编号是多少?
画图分析:
代码实现
bool Joseph(LoopLinkList& List, int interval){
const LinkNode* const head = List.list;
//遍历结点
LinkNode* current = List.list;
//待出列的结点
LinkNode* deleteNode = nullptr;
//返回值
bool ret = true;
int i = 0;//报数
int j = 0;//报数的数量
int times = 0;//当前进行第几轮 轮数
ElemType num{};
do {
if (!List.size || current->next == head) {
cerr << "链表为空!" << endl;
ret = false;
break;
}
if (interval < 1) {
cerr << "报数的数目太低!" << endl;
ret = false;
break;
}
do{
i += interval;
//查找 第i个结点 current 指向该结点的上一个结点
while (current->next){
if (current->next!= head) {
++j;
}
if (j >= i) {
break;
}
current = current->next;
}
++times;
if (current->next) {
deleteNode = current->next;//临时保存被删的结点以备释放
}
//deleteNode = current->next;
if (deleteNode){
num = deleteNode->value;
}
if (times==5){
cout << "第" << times << "出圈的编号:" << num << endl;
cout << endl;
}
if (deleteNode) {
cout << " 当前结点: " << num << "\t上一个结点: " << current->value << "\t 下一个结点:" << deleteNode->next->value << endl;
cout << endl;
}
if (deleteNode) {
current->next = deleteNode->next;
}
delete deleteNode;//释放被删的结点
showLoopLinkList(List);
cout << endl;
} while (List.list->next != head);
cout << "最后出圈的编号:" << num << endl;
cout << endl;
} while (false);
return ret;
}
约瑟夫问题运行结果:
链表数据元素为:1 链表数据元素为:2 链表数据元素为:3 链表数据元素为:4 链表数据元素为:5 链表数据元素为:6 链表数据元素为:7 链表数据元素为:8 链表数据元素为:9 链表数据元素为:10
当前结点: 9 上一个结点: 8 下一个结点:10
链表数据元素为:1 链表数据元素为:2 链表数据元素为:3 链表数据元素为:4 链表数据元素为:5 链表数据元素为:6 链表数据元素为:7 链表数据元素为:8 链表数据元素为:10
当前结点: 8 上一个结点: 7 下一个结点:10
链表数据元素为:1 链表数据元素为:2 链表数据元素为:3 链表数据元素为:4 链表数据元素为:5 链表数据元素为:6 链表数据元素为:7 链表数据元素为:10
当前结点: 10 上一个结点: 7 下一个结点:-842150451
链表数据元素为:1 链表数据元素为:2 链表数据元素为:3 链表数据元素为:4 链表数据元素为:5 链表数据元素为:6 链表数据元素为:7
当前结点: 2 上一个结点: 1 下一个结点:3
链表数据元素为:1 链表数据元素为:3 链表数据元素为:4 链表数据元素为:5 链表数据元素为:6 链表数据元素为:7
第5出圈的编号:5
当前结点: 5 上一个结点: 4 下一个结点:6
链表数据元素为:1 链表数据元素为:3 链表数据元素为:4 链表数据元素为:6 链表数据元素为:7
当前结点: 3 上一个结点: 1 下一个结点:4
链表数据元素为:1 链表数据元素为:4 链表数据元素为:6 链表数据元素为:7
当前结点: 4 上一个结点: 1 下一个结点:6
链表数据元素为:1 链表数据元素为:6 链表数据元素为:7
当前结点: 1 上一个结点: -842150451 下一个结点:6
链表数据元素为:6 链表数据元素为:7
当前结点: 6 上一个结点: -842150451 下一个结点:7
链表数据元素为:7
当前结点: 7 上一个结点: -842150451 下一个结点:-842150451
最后出圈的编号:7