C语言双向循环链表

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define LINE (struct Student *)

struct Student
{
int num;
float score;
/char name[20];/
struct Student *next;
struct Student *prior;
};

static int n = 0;

struct Student *creat(void) //创建双向循环链表
{
struct Student *head, *p1, *p2;
int i, w;
head = LINE malloc(sizeof(struct Student)); //给head分配内存空间
head->num = 0;
head->score = 0.0; //对head数据进行初始化
head->next = head;
head->prior = head; //head头和尾都指向自己本身
p1 = p2 = head;
printf(“请输入节点个数:\n”);
scanf("%d", &w);
printf("----请输入学号和成绩----\n"); //循环创建节点
for (i = 0; i<w; i++)
{
p1->next = LINE malloc(sizeof(struct Student)); //为p1分配地址空间
scanf("%ld%5f", &p1->next->num, &p1->next->score);
p1 = p1->next; //给p1的赋值
p1->prior = p2; //p1的头部指向p2
p2 = p2->next; //p2尾部指向p1
}
p1->next = head; //p1最后的尾部重新回到head实现循环
head->prior = p1; //head头部指向p1实现双向循环
return head;
}

int getListlength(struct Student *node) //获取链表长度
{
struct Student *length;
int len = 0; //统计链表的节点个数
length = node->next; //length指向第一个节点
while (length != node) //直到length循环链表一圈
{
len++;
length = length->next; //指向下一节点
}
return len; //返回链表长度
}
struct Student *node(struct Student *node, int n) //寻找目标节点
{
struct Student *p;
int i;
p = node;
for (i = 0; i <n; i++)
{
p = p->next; //遍历寻找节点
}
return p; //找到后返回该节点
}

void print_nodeshun(struct Student *head) //顺序输出节点
{
struct Student *p;
p = head->next;
printf("----链表内容输出如下----:\n");
if (head != NULL)
{
do{
printf("%ld,%5.1f\n", p->num, p->score);
//p = p->prior; //指向前一个节点并输出
p = p->next; //指向后一个节点并输出
_sleep(500);
} while (p->num != 0); //循环输出
}
}

void print_nodeni(struct Student *head) //逆序输出节点
{
struct Student *p;
p = head->prior;
printf("----链表内容输出如下----:\n");
if (head != NULL)
{
do{
printf("%ld,%5.1f\n", p->num, p->score);
p = p->prior; //指向前一个节点并输出
//p = p->next; //指向后一个节点并输出
_sleep(500);
} while (p->num != 0);

}

}
void add_node(struct Student *p, int n) //添加节点
{
struct Student *q, *New;
q = node(p, n); //目标节点
New = LINE malloc(sizeof(struct Student)); //为新节点分配空间
printf(“请给新增的节点输入数据:\n”);
scanf("%ld%f", &New->num, &New->score); //新节点输入数据
New->next = q; //新节点的尾部指向原节点
New->prior = q->prior; //新节点的首部指向原节点首部

q->prior->next = New;                                     //原节点的上一节点的next指向新节点
//原节点的上一节点的prior不变

q->prior = New;                                             //原节点prior指向新节点
原节点next不变

}

void delete_node(struct Student *p, int n) //删除节点
{
struct Student *q;
q = node(p, n); //获取需要删除的节点
q->prior->next = q->next; //该节点的上一节点(next)指向该节点的下一节点
q->next->prior = q->prior; //该节点的下一节点(prior)指向该节点的上一节点

free(q);                                                     //释放该节点所占据的内存

}

void change_node(struct Student *p, int n) //修改节点
{
struct Student *ch;
int num;
float score;
ch = node(p, n); //获取需要修改数据的节点
printf(“该节点目前数据是:\n%ld%5.1f\n”, ch->num, ch->score);
printf(“请输入数据:\n”);
scanf("%ld%f", &num, &score);
ch->num = num; ch->score = score; //将变量的值赋给源节点
printf(“修改后的数据为:\n”);
printf("%ld %5.1f\n", ch->num, ch->score);
}

void find_context(struct Student *p, int n) //查询节点
{
struct Student *q;
q = node(p, n); //获取目标节点
printf(“该节点目前数据是:\n%ld %5.1f\n”, q->num, q->score);
}

int main()
{
struct Student *p;
int a, m, x, h, f, w, leng; //分别表示所用到的输入序号
char cp;
p = NULL;
show:printf("-----------------链表功能展示--------------------\n");
printf("|-----------------------------------------------|\n");
printf("|\t\t1.创建双向循环链表\t\t|\n");
printf("|\t\t2.增加节点\t\t\t|\n");
printf("|\t\t3.删除节点\t\t\t|\n");
printf("|\t\t4.修改节点\t\t\t|\n");
printf("|\t\t5.查询节点\t\t\t|\n");
printf("|\t\t6.显示内容\t\t\t|\n");
printf("|\t\t7.退出\t\t\t\t|\n");
printf("|-----------------------------------------------|\n");
printf("\n");

printf("\t----请输入上述功能序号\n");
scanf("%d", &a);
switch (a)
{
case 1:
	p = creat();
	printf("\t----链表已创建,是否执行其他操作?Y/N\n");
	scanf("%s", &cp);
	if (cp == 'Y' || cp == 'y')
	{
		goto show;
	}
	else
		goto BB;
case 2:
	if (p == NULL){ printf("链表为空,请先创建链表!\n"); goto show; }
add:printf("\t----在第几个节点前插入?\n");
	scanf("%d", &x);
	if (x<1||x > (leng = getListlength(p)) + 1)
	{
		printf("插入的位置不在节点范围内!请重新输入!\n");
		goto add;
	}
	add_node(p, x);
	printf("\t----节点已添加,是否执行其他操作?Y/N\n");
	scanf("%s", &cp);
	if (cp == 'Y' || cp == 'y')
	{
		goto show;
	}
	else
		goto BB;
case 3:
	if (p == NULL){ printf("链表为空,请先创建链表!\n"); goto show; }
det:printf("\t----删除第几个节点?\n");
	scanf("%d", &h);
	if (h<1||h > (leng = getListlength(p)) + 1)
	{
		printf("删除的节点不在范围内!请重新输入!\n");
		goto det;
	}
	delete_node(p, h);
	printf("\t----指定节点已删除,是否执行其他操作?Y/N\n");
	scanf("%s", &cp);
	if (cp == 'Y' || cp == 'y')
	{
		goto show;
	}
	else
		goto BB;
case 4:
	if (p == NULL){ printf("链表为空,请先创建链表!\n"); goto show; }
change:printf("\t----需要修改哪个节点?\n");
	scanf("%d", &f);
	if (f<1||f > (leng = getListlength(p)))
	{
		printf("修改的节点不在范围内!请重新输入!\n");
		goto change;
	}
	change_node(p, f);
	printf("\t----节点已修改完成,是否执行其他操作?Y/N\n");
	scanf("%s", &cp);
	if (cp == 'Y' || cp == 'y')
	{
		goto show;
	}
	else
		goto BB;
case 5:
	if (p == NULL){ printf("链表为空,请先创建链表!\n"); goto show; }
serach:printf("\t----需要查询哪个节点?\n");
	scanf("%d", &m);
	if (m<1||m > (leng = getListlength(p)))
	{
		printf("查询的节点不在范围内!请重新输入!\n");
		goto serach;
	}
	find_context(p, m);
	goto show;
	break;
case 6:
	if (p == NULL){ printf("链表为空\n"); goto show; }
	printf("\t顺序输出请按1,逆序输出请按2\n");
	scanf("%d", &w);
	switch (w)
	{
	case 1:
		print_nodeshun(p); goto show;
	case 2:
		print_nodeni(p); goto show;
	default:goto BB;
	}
	break;
case 7:
BB : printf("\t----感谢使用!----\n"); break;
default:printf("该功能暂未开放!\n"); break;
}
printf("\n");
system("pause");
return 0;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值