第三章:链表(二)

作业
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> 思维导图

相关推荐
Pou光明1 小时前
1_linux系统网络性能如何优化——几种开源网络协议栈比较
linux·运维·网络·网络协议·开源
工业甲酰苯胺1 小时前
C语言之输入输出
c语言·c++·算法
零光速2 小时前
数据处理与统计分析——10-Pandas可视化-Matplotlib的常用API
数据结构·python·数据分析·pandas·matplotlib
努力d小白2 小时前
leetcode98.验证二叉搜索树
算法
YueTann2 小时前
Leetcode SQL 刷题与答案-基础篇
sql·算法·leetcode
TianyaOAO2 小时前
inmp+discuz论坛
linux·运维·服务器
星光璀璨山河无恙2 小时前
【Linux】grep命令
大数据·linux
归寻太乙2 小时前
算法基础Day7(动态规划)
算法·动态规划
稳联技术3 小时前
科技潮头浪接天,一桥飞架两界连。EthernetIP转Profinet互译连
linux·服务器·网络
余额不足121383 小时前
C语言基础六:循环结构及面试上机题
c语言·开发语言