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;
}
上一篇: python实现插入算法
下一篇: 数组处理,矩阵转置