数据结构——单向循环链表、双链表、双向循环链表

目录

一、单向循环链表

  1.1 单向循环链表的概念

  1.2 单向循环链表的操作

    1.2.1 单向循环链表的创建

    1.2.2 单向循环链表的头插

    1.2.3 单向循环链表的遍历

    1.2.4 单向循环链表的头删

    1.2.5 单向循环链表的尾插

    1.2.6 单向循环链表的尾删

    1.2.7 约瑟夫环

  1.3 单向循环列表所有程序

    1.3.1 head.h

    1.3.2 main.c

    1.3.3 fun.c

  1.4 输出效果

二、双链表

  2.1 双链表的概念

  2.2 双链表的操作

    2.2.1 双链表的创建

    2.2.2 双链表的头插

    2.2.3 双链表的遍历

    2.2.4 双链表的头删

    2.2.5 双链表的尾插

    2.2.6 双链表的尾删

  2.3 双链表所有程序

    2.3.1 head.h

    2.3.2 main.c

    2.3.3 fun.c

  2.4 输出效果

三、双向循环列表

  3.1 双向循环链表的概念

  3.2 双向循环链表的操作

    3.2.1 双向循环链表的创建

    3.2.2 双向循环链表的头插

    3.2.3 双向循环链表的遍历

    3.2.4 双向循环链表的头删

    3.2.5 双向循环链表的尾插

    3.2.6 双向循环链表的尾删

  3.3 双向循环链表所有程序

    3.3.1 head.h

    3.3.2 main.c

    3.3.3 fun.c

  3.4 输出效果


一、单向循环链表

  1.1 单向循环链表的概念

        1.单向循环链表:尾节点的指针域指向头结点的地址

        2.单向循环链表的节点:数据域和指针域

        数据域:存储的数据元素

        指针域:存储节点之间的关系,下一个节点的地址,单向循环链表的指针域指向该节点的地址

  1.2 单向循环链表的操作

    1.2.1 单向循环链表的创建

// 创建单向循环链表---------------
Linklist creat_node()
{
	// 1.创建一个新的节点
	Linklist s=(Linklist)malloc(sizeof(struct Node));
	// 2. 
	if(NULL==s)
		return NULL;
	// 初始化新节点的数据域
	s->data=0;
	// 初始化新节点的指针域
	s->next=s;
	return s;
}

    1.2.2 单向循环链表的头插

// 头插---------------
Linklist insert_head(Linklist head,datatype element)
{
	Linklist s=creat_node();
	s->data=element;
	// 1.判断链表是否为空
	if(NULL==head)
		head=s;
	else  // 链表中存在多个节点 >=1
	{
		// 找到尾节点
		Linklist del=head;
		while(del->next!=head)
		{
			del=del->next;
		}
		s->next=head;
		head=s;
		del->next=head;
	}
	return head;
}

    1.2.3 单向循环链表的遍历

// 循环遍历---------------
void output(Linklist head)
{
	//  1.判断链表是否为空
	if(NULL==head)
		return;
	// 2.循环遍历
	Linklist p=head;
	printf("Linklist=");
	do
	{
		printf("%d ",p->data);
		p=p->next;
	}while(p!=head);
	putchar(10);
	return;
}

    1.2.4 单向循环链表的头删

// 单向循环链表的头删---------------
Linklist delete_head(Linklist head)
{
	// 1.判断链表是否为空
	if(NULL==head)
		return head;
	// 2.判断链表是否为1
	if(head->next==head)
	{
		free(head);
		head=NULL;
		return head;
	}
	// 3.头删
	//  找到尾节点
	Linklist real=head;
	while(real->next!=head)
	{
		real=real->next;
	}
	Linklist del;
	del=head;
	head=head->next;
	free(del);
	del=NULL;
	real->next=head;
	return head;
}

    1.2.5 单向循环链表的尾插

// 单向循环链表的尾插---------------
Linklist insert_tail(Linklist head,datatype element)
{
	// 1.创建新节点,并输入值
	Linklist s=creat_node();
	s->data=element;
	s->next=head;
	// 2.判断链表是否为空
	if(NULL==head)
	{
		head=s;
	}
	else
	{
		// 3.尾插
		Linklist p=head;
		while(p->next!=head)  // 找到最后一个节点
		{
			p=p->next;
		}
		p->next=s;  // 链接:p指针域指向新节点的地址
	}
	return head;
}

    1.2.6 单向循环链表的尾删

// 单向循环链表的尾删---------------
Linklist delete_tail(Linklist head)
{
	// 1.判断链表是否为空
	if(NULL==head)
		return head;
	// 2.只有一个节点时
	else if(head->next==head)
	{
		free(head);
		head=NULL;
	}
	// 3.有多个节点时
	else
	{
		Linklist del=head;
		// 找到倒数第二个节点
		while(del->next->next!=head)
		{
			del=del->next;
		}
		// 删除p的后继
		free(del->next);
		del->next=head;
	}
		return head;
}

    1.2.7 约瑟夫环

        约瑟夫环:用循环链表编程实现约瑟夫问题

        n个人围成一圈,从某人开始报数1, 2, …, m,数到m的人出圈,然后从出圈的下一个人(m+1)开始重复此过程,直到 全部人出圈,于是得到一个出圈人员的新序列

        如当n=8,m=4时,若从第一个位置数起,则所得到的新的序列 为4, 8, 5, 2, 1, 3, 7, 6。

// 约瑟夫环
Linklist joseph(Linklist head,int n, int m)
{
	Linklist p=head;
	Linklist del=NULL;
	Linklist s=NULL;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<m-1;j++)
		{
			p=p->next;
		}
		del=p->next;
		p->next=p->next->next;
		p=p->next;
		if(i==1)
		{
			head=del;
			head->next=head;
		}
		else
		{
			s=head;
			while(s->next!=head)
			{
				s=s->next;
			}
			del->next=head;
			s->next=del;
		}
	}
	return head;
}

  1.3 单向循环列表所有程序

    1.3.1 head.h

#ifndef __HEAD_H__
#define __HEAD_H__

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef int datatype;
enum passble{SUCCSSES,FALSE=-1};
// 节点结构定义
// 节点:数据、指针域
// Node不可省略
typedef struct Node
{
	datatype data;  // 数据域:数据元素
	struct Node *next;  // 指针域:节点之间的关系,下一个节点的地址
}*Linklist;

Linklist creat_node();
Linklist insert_head(Linklist head,datatype element);
void output(Linklist head);
Linklist delete_head(Linklist);
Linklist insert_tail(Linklist head,datatype element);
Linklist delete_tail(Linklist head);
int get_len(Linklist head);
Linklist joseph(Linklist head,int n, int m);

#endif

    1.3.2 main.c

#include "head.h"
int main(int argc, const char *argv[])
{
// 单向循环链表的创建
// 单向循环链表的头插
	Linklist head=NULL;
	int n;
	printf("请输入插入个数:");
	scanf("%d",&n);
	datatype element;
	for(int i=0;i<n;i++)
	{
		printf("请输入插入的第 %d 个元素:",i+1);
		scanf("%d",&element);
		head=insert_head(head,element);
	}
	output(head);

// 单向循环链表的头删
	head=delete_head(head);
	printf("头删后");
	output(head);
// 单向循环链表的尾插
	printf("请输入尾插个数:");
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		printf("请输入尾插元素:");
		scanf("%d",&element);
		head=insert_tail(head,element);
	}
	output(head);

// 单向循环链表的尾删
	head=delete_tail(head);
	printf("尾删后");
	output(head);
	
// 约瑟夫环
	int m=4;
	head=joseph(head,n,m);
	output(head);

	return 0;
}

    1.3.3 fun.c

#include "head.h"
// 创建单向循环链表---------------
Linklist creat_node()
{
	// 1.创建一个新的节点
	Linklist s=(Linklist)malloc(sizeof(struct Node));
	// 2. 
	if(NULL==s)
		return NULL;
	// 初始化新节点的数据域
	s->data=0;
	// 初始化新节点的指针域
	s->next=s;
	return s;
}
// 头插---------------
Linklist i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值