双向循环链表的实践(C语言+详细注释)

要求:实现用户输入一个数使得26个字母的排列发生变化
例如用户输入3
输出结果:DEFGHIJKLMNOPQRSTUVWXYZABC
同时需要支持负数
例如用户输入-3,
输出结果:XYZABCDEFGHIJKLMNOPQRSTUVW

本题构建带头结点的双向循环链表,但头结点不再循环内,这样有利于尾节点和首节点的无缝连接,操作跟简单。

程序代码如下:

#include<stdio.h>
#include<stdlib.h>

#define OK       1
#define ERROR    0

typedef  char  Elemtype;                         //数据类型重定义 
typedef int  Status;                             //状态类型重定义 

typedef struct DualNode{ 
	Elemtype data;                               //数据域 
	struct DualNode *prior;                      //节点前驱指针 
	struct DualNode *next;                       //节点后继指针 
}DualNode,*DuLinklist;

/*双向循环链表初始化,头结点不再循环内*/ 
Status InitList(DuLinklist *L) 
{
	int i;
	DualNode *p,*q;
	*L=(DuLinklist)malloc(sizeof(DualNode));          //创建头结点 
	if(!(*L))                                         //异常判断 
	{
		return ERROR;
	}
	(*L)->prior=(*L)->next=*L;                       //将头结点的前驱指针和后继指针指向本身 
	p=(*L);
	for(i=0;i<26;i++)
	{
		q=(DuLinklist)malloc(sizeof(DualNode));     //创建新节点 
		if(!q)                                     //异常判断 
		{
			return ERROR;
		}
		q->data='A'+i;
		q->prior=p;                               //将创建节点的前驱指针指向上一个节点 
		p->next=q;                                //将上一节点的后继指针指向新创建节点 
		p=q;                                      //将指针指向尾节点	
	}
	p->next=(*L)->next;                           //将尾节点的后继指针指向首节点 
	(*L)->next->prior=q;                          //将首节点的前驱指针指向尾指针 
	
	return OK;
}

void Move(DuLinklist *L,int i)
{
	if(i>0)                                    //将元素正向移动 
	{
		do{
			 (*L)=(*L)->next;                  //将指针移到链表正向第i个开始正向输出 
		  }while(--i);
	}
	if(i<0)
	{
		i=i-1;
		(*L)=(*L)->next;                      //将指针指向首节点 
		do{
			 (*L)=(*L)->prior;               //后继转前继将指针移到链表逆向第i个开始正向输出
		  }while(++i);
	}
}

void Display(DuLinklist *L)                 //链表输出函数 
{
	int i;
	for(i=0;i<26;i++)
	{
		(*L)=(*L)->next;
		printf("%c",(*L)->data);
	}
}
int main()
{
	int n;
	DuLinklist L;
	InitList(&L);
	Display(&L);//输出初始化链表 
	printf("\n");
	printf("请输入移动元素的个数:"); 
	scanf("%d",&n);
	Move(&L,n);//移动操作 
	Display(&L);//输出移动后的链表 
	return 0;
}

运行效果截图如下:
在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值