第三章:链表(二)

作业
1> 使用单向循环链表完成约瑟夫环问题

cpp 复制代码
/*******************************************************/
//=> File Name: yuesefuhuan.h
//=> Author: Water
//=> Mail: 1249496568@qq.com 
//=> Created Time: 2024年12月02日 星期一 18时47分59秒
/*******************************************************/

#ifndef YUESEFUHUAN_H
#define YUESEFUHUAN_H
#include<myhead.h>

typedef int datatype;

typedef struct Node
{
	union
	{
		int len;
		datatype data;
	};
	struct Node * next;
}Node,* Node_ptr;

//创建单向循环链表
Node_ptr list_create();
//申请结点
Node_ptr list_node_apply(datatype e);
//判空
int list_empty(Node_ptr L);
//头插
int list_insert_head(Node_ptr L,datatype e);
//尾插
int list_insert_tail(Node_ptr L,datatype e);
//遍历
void list_show(Node_ptr L);
//删除头结点
Node_ptr list_head_delete(Node_ptr L);
//约瑟夫循环列出
int list_yuesefu(Node_ptr L,int pos);
//销毁链表
void list_destroy(Node_ptr L);

#endif
cpp 复制代码
/*******************************************************/
//=> File Name: yuesefuhuan.c
//=> Author: Water
//=> Mail: 1249496568@qq.com 
//=> Created Time: 2024年12月02日 星期一 18时47分59秒
/*******************************************************/

#include"yuesefuhuan.h"

//创建单向循环链表
Node_ptr list_create()
{
	Node_ptr L = (Node_ptr)malloc(sizeof(Node));
	if(NULL == L)
	{
		printf("链表不合法\n");
		return NULL;
	}
	L->len = 0;
	L->next = L;
	return L;
}
//申请结点
Node_ptr list_node_apply(datatype e)
{
	Node_ptr p = (Node_ptr)malloc(sizeof(Node));
	if(NULL == p)
	{
		printf("结点申请失败\n");
		return NULL;
	}
	p->data = e;
	p->next = NULL;
	return p;
}
//判空
int list_empty(Node_ptr L)
{
	if(NULL == L)
	{
		printf("链表不合法\n");
		return -1;
	}
	return L->next == L;
}
//头插
int list_insert_head(Node_ptr L,datatype e)
{
	if(NULL == L)
	{
		printf("链表不合法\n");
		return -1;
	}
	Node_ptr p = list_node_apply(e);
	if(NULL == p)
	{
		return -1;
	}
	p->next = L->next;
	L->next = p;
	L->len++;
	printf("头插成功\n");
	return 0;
}
//尾插
int list_insert_tail(Node_ptr L,datatype e)
{
	if(NULL == L)
	{
		printf("链表不合法\n");
		return -1;
	}
	Node_ptr p = list_node_apply(e);
	if(NULL == p)
	{
		return -1;
	}
	Node_ptr q = L;
	while(q->next != L)
	{
		q = q->next;
	}
	p->next = q->next;
	q->next = p;
	L->len++;
	printf("尾插成功\n");
	return 0;
}
//遍历
void list_show(Node_ptr L)
{
	if(NULL == L || list_empty(L))
	{
		printf("遍历失败\n");
		return;
	}
	Node_ptr p = L->next;
	printf("该约瑟夫环人员编号分别为:\n");
	do
	{
		printf("%d\t",p->data);
		p = p->next;
	}while(p != L);
	printf("\n");
	return;
}
//删除头结点
Node_ptr list_head_delete(Node_ptr L)
{
	if(NULL == L)
	{
		printf("删除头结点失败\n");
		return NULL;
	}
	if(list_empty(L))
	{
		free(L);
		printf("删除头结点成功\n");
		return NULL;
	}
	Node_ptr q = L->next;
	while(q->next != L)
	{
		q = q->next;
	}
	q->next = L->next;
	free(L);
	L = NULL;
	printf("删除头结点成功\n");
	return q->next;
}
//约瑟夫循环列出
int list_yuesefu(Node_ptr L,int step)
{
	if(NULL == L || list_empty(L))
	{
		printf("淘汰失败\n");
		return -1;
	}
	Node_ptr p = list_head_delete(L);
//定义计数标志
	int count = 0;

	printf("出列顺序为:\n");
	//循环到只有最后一个节点
	while (p->next != p)
	{
		//计数增加
		count++;
		//每计数到二进行头删操作,删除第三个节点
		if (count == step-1)
		{
			printf("%d\t",p->next->data);
			Node_ptr q = p->next;
			p->next = q->next;
			free(q);
			q = NULL;
			count = 0;
		}
		//遍历指针后移
		p = p->next;		
	}
	//输出最后一个节点
	printf("%d\n",p->data);
	list_destroy(p);
	return 0;
}
//销毁
void list_destroy(Node_ptr H)
{
	if(NULL == H)
	{
		printf("循环单向链表销毁失败\n");
		return;
	}
	while(H->next != H)
	{
		Node_ptr p = H->next;
		H->next = p->next;
		free(p);
		p = NULL;
	}
	free(H);
	H = NULL;
	printf("循环单向链表销毁成功\n");
	return;
}
cpp 复制代码
/*******************************************************/
//=> File Name: main.c
//=> Author: Water
//=> Mail: 1249496568@qq.com 
//=> Created Time: 2024年12月02日 星期一 18时47分59秒
/*******************************************************/

#include"yuesefuhuan.h"
int main(int argc, const char *argv[])
{
	Node_ptr L = list_create();
	if(NULL == L)
	{
		return -1;
	}
	int num = 0;
	printf("请输入组成约瑟夫环的人数:");
	scanf("%d",&num);
	for(int i=1,e=num;i<=num;i++,e--)
	{
		list_insert_head(L,e);
	}
	printf("%d人已成功列入该单向循环链表\n",num);
	list_show(L);
	int step = 0;
	printf("请输入约瑟夫环的淘汰间隔数:");
	scanf("%d",&step);
	list_yuesefu(L,step);
	return 0;
}

2> 双向链表和循环链表整体代码手动实现一遍(至少要完成增删改查操作)

//双向链表

cpp 复制代码
/*******************************************************/
//=> File Name: doublelinklist.h
//=> Author: Water
//=> Mail: 1249496568@qq.com 
//=> Created Time: 2024年12月02日 星期一 10时21分08秒
/*******************************************************/

#ifndef DOUBLELINKLIST_H
#define DOUBLELINKLIST_H
#include<myhead.h>

typedef char datatype;

typedef struct Node
{
	union
	{
		datatype data;
		int len;
	};
	struct Node * prio;
	struct Node * next;
}Node,*Node_ptr;

//创建双向链表
Node_ptr list_create();
//判空
int list_empty(Node_ptr L);
//头插
int list_insert_head(Node_ptr L,datatype e);
//遍历
void list_show(Node_ptr L);
//按位置查找返回结点
Node_ptr list_search_pos(Node_ptr L,int pos);
//任意位置插入
int list_insert_pos(Node_ptr L,int pos,datatype e);
//头删
int list_delete_head(Node_ptr L);
//任意位置删除
int list_delete_pos(Node_ptr L,int pos);
//按位置修改
int list_update_pos(Node_ptr L,int pos,datatype e);
//销毁双向链表
void list_destory(Node_ptr L);

#endif
cpp 复制代码
/*******************************************************/
//=> File Name: doublelinklist.c
//=> Author: Water
//=> Mail: 1249496568@qq.com 
//=> Created Time: 2024年12月02日 星期一 10时21分08秒
/*******************************************************/

#include"doublelinklist.h"
//创建双向链表
Node_ptr list_create()
{
	//堆区申请一个头结点的大小
	Node_ptr L = (Node_ptr)malloc(sizeof(Node));
	if(NULL == L)
	{
		printf("双向链表创建失败\n");
		return NULL;
	}
	//初始化头结点
	L->len = 0;
	L->prio = NULL;
	L->next = NULL;
	printf("双向链表创建成功\n");
	return L;
}
//定义申请结点封装数据函数
static Node_ptr list_node_apply(datatype e)
{
	//堆区申请一个结点
	Node_ptr p = (Node_ptr)malloc(sizeof(Node));
	if(NULL == p)
	{
		printf("结点申请失败");
		return NULL;
	}
	//将数据封装进数据域
	p->data = e;
	p->prio = NULL;
	p->next = NULL;
	return p;
}
//判空
int list_empty(Node_ptr L)
{
	if(NULL == L)
	{
		printf("链表不合法\n");
		return -1;
	}
	return L->next == NULL;
}
//头插
int list_insert_head(Node_ptr L,datatype e)
{
	if(NULL == L)
	{
		printf("链表不合法");
		return -1;
	}
	Node_ptr p = list_node_apply(e);
	if(NULL == p)
	{
		return -1;
	}
	if(list_empty(L))
	{
		//链表为空
		p->prio = L;
		L->next = p;
	}
	else
	{
		p->next = L->next;
		p->prio = L;
		L->next->prio = p;
		L->next = p;
	}
	L->len++;
	printf("头插成功\n");
	return 0;
}
//遍历
void list_show(Node_ptr L)
{
	if(NULL == L || list_empty(L))
	{
		printf("遍历失败\n");
		return;
	}
	printf("当前双向链表的元素分别为:\n");
	Node_ptr q = L->next;
	while(q != NULL)
	{
		printf("%c\t",q->data);
		q = q->next;
	}
	printf("\n");
}
//按位置查找返回结点
Node_ptr list_search_pos(Node_ptr L,int pos)
{
	if(NULL == L || list_empty(L) || pos<0 || pos>L->len)
	{
		printf("查找失败\n");
		return NULL;
	}
	Node_ptr q = L;
	for(int i=0;i<pos;i++)
	{
		q = q->next;
	}
	return q;
}
//任意位置插入
int list_insert_pos(Node_ptr L,int pos,datatype e)
{
	if(NULL == L)
	{
		printf("链表不合法");
		return -1;
	}
	Node_ptr p = list_node_apply(e);
	Node_ptr q = list_search_pos(L,pos-1);
	if(NULL == p)
	{
		return -1;
	}
	if(q->next == NULL)
	{
		//尾插
		p->prio = q;
		q->next = p;
	}
	else
	{
		p->next = q->next;
		p->prio = q;
		q->next->prio = p;
		q->next = p;
	}
	L->len++;
	printf("第%d位插入成功\n",pos);
	return 0;
}
//头删
int list_delete_head(Node_ptr L)
{
	if(NULL == L || list_empty(L))
	{
		printf("头删失败\n");
		return -1;
	}
	Node_ptr p = L->next;
	L->next = p->next;
	if(p->next == NULL)
		L->next = NULL;
	else
		p->next->prio = L;
	free(p);
	p = NULL;
	printf("头删成功\n");
	return 0;
}
//任意位置删除
int list_delete_pos(Node_ptr L,int pos)
{
	if(NULL == L || list_empty(L))
	{
		printf("按位置删除失败\n");
		return -1;
	}
	Node_ptr q = list_search_pos(L,pos-1);
	Node_ptr p = q->next;
	q->next = p->next;
	if(p->next == NULL)
		q->next = NULL;
	else
		p->next->prio = q;
	free(p);
	p = NULL;
	printf("第%d位删除成功\n",pos);
	return 0;
}
//按位置修改
int list_update_pos(Node_ptr L,int pos,datatype e)
{
	if(NULL == L || list_empty(L) || pos<1 || pos>L->len)
	{
		printf("按位置修改失败\n");
		return -1;
	}
	Node_ptr p = list_search_pos(L,pos);
	p->data = e;
	printf("第%d位修改成功\n",pos);
	return 0;
}
//销毁双向链表
void list_destory(Node_ptr L)
{
	if(NULL == L)
	{
		printf("销毁双向链表失败\n");
		return;
	}
	while(!list_delete_head(L))
	{
		list_delete_head(L);
	}
	free(L);
	L = NULL;
	printf("销毁双向链表成功\n");
	return;
}
cpp 复制代码
/*******************************************************/
//=> File Name: main.c
//=> Author: Water
//=> Mail: 1249496568@qq.com 
//=> Created Time: 2024年12月02日 星期一 10时21分08秒
/*******************************************************/

#include"doublelinklist.h"
int main(int argc, const char *argv[])
{
	Node_ptr L = list_create();
	if(NULL == L)
	{
		return -1;
	}
	list_insert_head(L,'h');
	list_insert_head(L,'e');
	list_insert_head(L,'l');
	list_insert_head(L,'l');
	list_insert_head(L,'o');
	list_show(L);
	list_insert_pos(L,3,'w');
	list_show(L);
	list_insert_pos(L,7,'k');
	list_show(L);
	list_delete_head(L);
	list_show(L);
	list_delete_pos(L,3);
	list_show(L);
	list_delete_pos(L,5);
	list_show(L);
	list_update_pos(L,3,'k');
	list_show(L);
	list_destory(L);
	list_show(L);
	return 0;
}

//单向循环链表

cpp 复制代码
/*******************************************************/
//=> File Name: looplinklist.h
//=> Author: Water
//=> Mail: 1249496568@qq.com 
//=> Created Time: 2024年12月02日 星期一 15时46分12秒
/*******************************************************/

#ifndef LOOPLINKLIST_H
#define LOOPLINKLIST_H
#include<myhead.h>

typedef char datatype;

//定义结点结构体
typedef struct Node
{
	union
	{
		int len;
		datatype data;
	};
	struct Node *next;
}Node,* Node_ptr;

//创建循环单向链表
Node_ptr list_create();
//判空
int list_empty(Node_ptr L);
//尾插
int list_insert_tail(Node_ptr L,datatype e);
//遍历
void list_show(Node_ptr L);
//尾删
int list_delete_tail(Node_ptr L);
//删除头结点
Node_ptr list_head_delete(Node_ptr L);
//删除头结点后的遍历
void list_desplay(Node_ptr H);
//销毁
void list_destroy(Node_ptr H);

#endif
cpp 复制代码
/*******************************************************/
//=> File Name: looplinklist.c
//=> Author: Water
//=> Mail: 1249496568@qq.com 
//=> Created Time: 2024年12月02日 星期一 15时46分34秒
/*******************************************************/

#include"looplinklist.h"
//创建循环单向链表
Node_ptr list_create()
{
	Node_ptr L = (Node_ptr)malloc(sizeof(Node));
	if(NULL == L)
	{
		printf("创建循环单向链表失败\n");
		return NULL;
	}
	L->len = 0;
	L->next = L;
	return L;
}
//判空
int list_empty(Node_ptr L)
{
	if(NULL == L)
	{
		printf("该链表不合法");
		return -1;
	}
	return L->next == L;
}
//申请结点
static Node_ptr list_node_apply(datatype e)
{
	Node_ptr p = (Node_ptr)malloc(sizeof(Node));
	if(NULL == p)
	{
		printf("结点申请失败\n");
		return NULL;
	}
	return p;
}
//尾插
int list_insert_tail(Node_ptr L,datatype e)
{
	if(NULL == L)
	{
		printf("尾插失败\n");
		return -1;
	}
	Node_ptr q = L;
	while(q->next != L)
	{
		q = q->next;
	}
	Node_ptr p = list_node_apply(e);
	p->data = e;
	p->next = NULL;
	//插入
	p->next = L;
	q->next = p;
	L->len++;
	printf("尾插成功\n");
	return 0;
}
//遍历
void list_show(Node_ptr L)
{
	if(NULL == L || list_empty(L))
	{
		printf("遍历失败\n");
		return;
	}
	printf("该循环单向链表为:\n");
	Node_ptr q = L->next;
	while(q != L)
	{
		printf("%c\t",q->data);
		q = q->next;
	}
	printf("\n");
}
//尾删
int list_delete_tail(Node_ptr L)
{
	if(NULL == L || list_empty(L))
	{
		printf("尾删失败\n");
		return -1;
	}
	Node_ptr q = L;
	while(q->next->next != L)
	{
		q = q->next;
	}
	free(q->next);
	q->next = L;
	L->len--;
	printf("尾删成功\n");
	return 0;
}
//删除头结点
Node_ptr list_head_delete(Node_ptr L)
{
	if(NULL == L)
	{
		printf("删除头结点失败\n");
		return NULL;
	}
	if(list_empty(L))
	{
		free(L);
		printf("删除头结点成功\n");
		return NULL;
	}
	Node_ptr q = L->next;
	while(q->next != L)
	{
		q = q->next;
	}
	q->next = L->next;
	free(L);
	L = NULL;
	printf("删除头结点成功\n");
	return q->next;
}
//删除头结点后的遍历
void list_desplay(Node_ptr H)
{
	if(NULL == H)
	{
		printf("删除头结点后遍历遍历失败\n");
		return;
	}
	printf("该循环单向链表为:\n");
	Node_ptr q = H;
	do
	{
		printf("%c\t",q->data);
		q = q->next;
	}while(q != H);
	printf("\n");
}
//销毁
void list_destroy(Node_ptr H)
{
	if(NULL == H)
	{
		printf("循环单向链表销毁失败\n");
		return;
	}
	while(H->next != H)
	{
		Node_ptr p = H->next;
		H->next = p->next;
		free(p);
		p = NULL;
	}
	free(H);
	H = NULL;
	printf("循环单向链表销毁成功\n");
	return;
}
cpp 复制代码
/*******************************************************/
//=> File Name: main.c
//=> Author: Water
//=> Mail: 1249496568@qq.com 
//=> Created Time: 2024年12月02日 星期一 15时46分34秒
/*******************************************************/

#include"looplinklist.h"
int main(int argc, const char *argv[])
{
	Node_ptr L = list_create();
	if(NULL == L)
	{
		return -1;
	}
	list_insert_tail(L,'h');
	list_insert_tail(L,'e');
	list_insert_tail(L,'l');
	list_insert_tail(L,'l');
	list_insert_tail(L,'o');
	list_show(L);
	list_delete_tail(L);
	list_show(L);
	Node_ptr H = list_head_delete(L);
	list_desplay(H);
	list_destroy(H);
	H = NULL;
	list_desplay(H);
	return 0;
}

3> 思维导图

相关推荐
Hello.Reader3 分钟前
算法基础(三)—— 插入排序从整理扑克牌到有序数组
java·算法·排序算法
50万马克的面包3 分钟前
C语言:三大基础排序算法模板 冒泡 / 选择 / 插入)
c语言·笔记·算法·排序算法
罗超驿4 分钟前
3.快乐数专题学习笔记——双指针法在LeetCode 202题中的应用
java·算法·leetcode·职场和发展
无限进步_6 分钟前
【C++】深入底层:自己动手实现一个哈希表
开发语言·数据结构·c++·算法·链表·散列表·visual studio
_深海凉_8 分钟前
LeetCode热题100-小于 n 的最大数(字节高频题)
算法·leetcode·职场和发展
小雅痞13 分钟前
[Java][Leetcode middle] 36. 有效的数独
java·算法·leetcode
IT菜鸟程15 分钟前
Linux 系统安全加固实战:从密码策略到 SSH 访问控制
linux·ssh·系统安全
cen__y15 分钟前
Linux10(计算机网络01)
linux·运维·服务器·c语言·计算机网络·ubuntu
paeamecium16 分钟前
【PAT甲级真题】- General Palindromic Number(20)
数据结构·c++·算法·pat考试·pat
minji...17 分钟前
Linux 网络基础之UDP协议(四)传输层协议 UDP,再谈端口号,UDP 特点
linux·服务器·开发语言·网络·c++·tcp/ip·udp