C/C++对大一C语言的课程设计——KTV点歌系统的介绍(链表)

个人主页:

仍有未知等待探索_洛谷刷题,小项目,数据结构-CSDN博客

专题分栏---小项目

小项目_仍有未知等待探索的博客-CSDN博客

————————————— 与2023年12月28日进行更新 ————————————————

写此博客的目的:一是为了让自己对链表的思考方式更加的清晰,二是对不清楚链表实现方式的讲解!

所有的菜单都没有进行讲解,太简单。另外建议写这种比较大的程序的时候,不要着急先写菜单,要先把每一个功能实现完之后在开始准备菜单。

如果有错误,洗耳恭听。可能写的没有那么明白,请见谅!

目录

一、KTV点歌系统的需要实现的功能介绍

二、对每个功能的实现 

 1、初始化歌曲库

2.1、点歌

2.2、排序--(按演唱者名字,按歌曲名字)

3.1、显示已点歌曲

3.2查询已点歌曲

3.3删除

3.4置顶

3.5上移一位 

三、总代码


一、KTV点歌系统的需要实现的功能介绍

  1. 设计并实现一个KTV点歌程序,实现点歌功能。要求实现二级菜单:
        1. 初始化歌曲库。(包括歌曲的名称、演唱者)
        2. 点歌
        3. 已点歌曲

请选择:

       选择2. 点歌,显示二级菜单:

  1. 按照歌曲的拼音字母排序显示;
  2. 按照演唱者的名字排序显示

请选择

选择歌曲后将歌曲添加到已点列表。

选择3.已选歌曲,显示二级菜单:

  1. 显示已点歌曲
  2. 查询已点歌曲
  3. 删除已点歌曲
  4. 置顶
  5. 上移一位

请选择:

功能说明:

  1. 显示已点歌曲:按照点歌顺序显示已点歌曲;
  2. 查询已点歌曲:输入查询歌曲名称后进行查询,若存在显示歌名以及序号;若不存在,显示:未点播此歌曲;
  3. 删除已点歌曲:在显示已点歌曲后,输入删除歌曲序号,将次歌曲删除,并重新排列序号。例如:“1.if you  2.红颜乱  3.凉凉”删除1.if you 后,显示“1.红颜乱  2.凉凉”;
  4. 置顶:在显示已点歌曲后,选择置顶歌曲的序号,将歌曲置顶,并重新排序列号。例如:“1.if you  2.红颜乱  3.凉凉”选择置顶歌曲:3.凉凉后,显示“1.凉凉 2.if you 3.红颜乱”;
  5. 上移一位:在显示已点歌曲后,选择上移一位歌曲的序号,将该歌曲上移一位后,重新排列序号。例如:“1.if you  2.红颜乱  3.凉凉”选择上移一位歌曲:3.凉凉后,显示“1.if you  2.凉凉  3.红颜乱”。

二、对每个功能的实现 

 1、初始化歌曲库

每个人对于初始化歌曲库的理解不太相同,我理解的初始化歌曲库就是你在点歌前系统里面自带的歌曲。对于这个功能的实现代码如下:

struct song* Initlinklist()
{
	struct song* head, * s, * tail;
	head = NULL;
	s = (struct song*)malloc(sizeof(struct song));
	s->num = 1;
	strcpy(s->song_name, "左手右手");
	strcpy(s->man_name, "郭子荷");
	s->next = NULL;
	head = s;
	tail = s;
	s = s->next;
	s = (struct song*)malloc(sizeof(struct song));
	s->num = 2;
	strcpy(s->song_name, "红颜乱");
	strcpy(s->man_name, "刘涛");
	tail->next = s;
	tail = tail->next;
	s = (struct song*)malloc(sizeof(struct song));
	s->num = 3;
	strcpy(s->song_name, "凉凉");
	strcpy(s->man_name, "张碧晨");
	s->next = NULL;
	tail->next = s;
	tail = tail->next;
	count = 3;
	return head;
}

C/C++对大一C语言的课程设计——KTV点歌系统的介绍(链表)_第1张图片

 如上代码的具体含义就是图片所展示的,通过最朴素的方法创建3个节点,然后对其进行连接,连接的方式就是让next这个指针指向下一个节点的地址,尾节点的next指向NULL。不要忘了要用一个头指针指向头节点的地址(头指针不能轻易的移动),要不然就找不到这个链表了。因为是初始化歌曲库功能,是系统中自带的歌曲(我自己认为的),所以就用这种方式写。

而且初始化歌曲库不仅仅只用系统自带的歌曲,也可以通过客户对其进行添加歌曲进入歌曲库中,添加歌曲的过程相当于创建链表的过程,但我之前已经有一个歌曲库的链表,所以添加的歌曲直接再现有的链表中继续延长即可,用循环的方式来进行多次的添加,用一个‘0’作为结束的标识。代码如下:

printf("是否手动添加歌曲进入歌曲库(Yes(y)/NO(n)):\n");
			char Isright = ' ';
			while (1)
			{
				getchar();
				Isright = getchar();
				if (Isright == 'y')
				{
					printf("请添加歌曲名称、歌手\n");
					s = (struct song*)malloc(sizeof(struct song));
					num = i;
					scanf("%s", song_name);
					scanf("%s", man_name);
					s->num = num;
					strcpy(s->song_name, song_name);
					strcpy(s->man_name, man_name);
					i++;
					count++;
					s->next = following->next;
					following->next = s;
				}
				else
				{
					system("pause");
					system("cls");
					break;
				}
				printf("是否继续手动添加歌曲进入歌曲库(Yes(y)/NO(n)):\n");
			}

创建一个新的链表的方式有头插和尾插两种,在原有的基础上延长链表更像尾插的方式,并且不需要考虑头指针是否为空,所以比较简单,另外需要注意的是字符串之间的复制操作要用字符串拷贝函数(strcpy)实现

2.1、点歌

点歌这个功能是需要一个新的链表,把用户所点的歌曲进行储存。最好再每个歌曲前面添加一个序号,极大的方便了用户的使用,并且这个功能还用个小坑,就是歌曲可以重复的点,到时候遍历用户所点的歌曲的时候需要重复的出现。而且我还用到了两个全局变量来记录我歌曲库中的歌曲数和用户所点的歌曲数(重复的按多次算)。

struct song* option(struct song* head, struct song* head1)
{
	struct song* s, * p, * tail;
	s = head;
	p = head1;
	tail = head1;
	int num, i = 1, index = 0;
	char song_name[20];
	char man_name[10];
	printf("请输入想选的歌曲序号(输入零结束):");
	scanf("%d", &num);
	while (num != 0)
	{
		s = head;
		if (num > count || num < 0)
		{
			printf("查无此序号歌曲,请重新输入:");
			scanf("%d", &num);
			continue;
		}
		int a = 1;
		for (i = 1; i <= count; i++)
		{
			if (s->num == num)
			{
				p = (struct song*)malloc(sizeof(struct song));
				p->num = a;
				strcpy(p->song_name, s->song_name);
				strcpy(p->man_name, s->man_name);
				if (head1 == NULL)
				{
					head1 = p;
					p->next = NULL;
					tail = p;
				}
				else
				{
					p->next = tail->next;
					tail->next = p;
					tail = tail->next;
				}
			}
			s = s->next;
			a++;
		}
		index = num;
		count1++;
		printf("请输入想选的歌曲序号(输入零结束):");
		scanf("%d", &num);
	}
	return head1;
}

需要注意的是如果用户所点的歌曲再歌曲库中没有的话,需要对其进行说明(也就是平常所说的合理性判断)

2.2、排序--(按演唱者名字,按歌曲名字)

链表和数组的明显区别是数组是开辟内存的一块完整的空间(比较浪费内存),而链表是分散的空间(省内存),但链表没用数组那么容易排序,不容易排序但可以排序,我链表排序中使用的方法是冒泡排序

如下代码展示的是按照歌曲名字排序的(演唱者名字排序与其大同小异):

struct song* songname_sort(struct song* head)
{
	struct song* p;
	p = head;
	int i = 0, flag = 0;
	char song_name[20];
	char man_name[20];
	for (i; i < count; i++)
	{
		p = head;
		while ((p->next)->next != NULL)
		{
			if (strcmp(p->song_name, (p->next)->song_name) == 1)
			{
				strcpy(song_name, p->song_name);
				strcpy(p->song_name, (p->next)->song_name);
				strcpy((p->next)->song_name, song_name);
				strcpy(man_name, p->man_name);
				strcpy(p->man_name, (p->next)->man_name);
				strcpy((p->next)->man_name, man_name);
			}
			p = p->next;
		}
		if (strcmp(p->song_name, (p->next)->song_name) == 1)
		{
			strcpy(song_name, p->song_name);
			strcpy(p->song_name, (p->next)->song_name);
			strcpy((p->next)->song_name, song_name);
			strcpy(man_name, p->man_name);
			strcpy(p->man_name, (p->next)->man_name);
			strcpy((p->next)->man_name, man_name);
		}
	}
	return head;
}

这个时候我创建的全局变量就开始发挥作用了,通过for循环来控制趟数,每一趟用 while循环来去进行排序,排序的时候需要数据之间的比较,这个程序中,比较的变量有两种:一个是演唱者的名字首字母,和歌曲名字的首字母,字符串之间的比较要用字符串比较函数(strcmp)来实现。

3.1、显示已点歌曲

说白了就是对于用户点歌的那个链表进行遍历而已。没有什么难点,就不过多解释了。

void pass(struct song* head)
{
	struct song* p;
	p = head;
	int i = 1;
	if (p == NULL)
	{
		printf("暂无点歌\n");
	}
	else
	{
		while (p->next != NULL)
		{
			p->num = i;
			printf("%d\t%-8s\t%s\n", p->num, p->song_name, p->man_name);
			p = p->next;
			i++;
		}
		p->num = i;
		printf("%d\t%-8s\t%s\n", p->num, p->song_name, p->man_name);
	}
}

3.2查询已点歌曲

查询已点歌曲和显示已点歌曲有异曲同工指出。显示是进行遍历然后打印再屏幕上,查询是进行遍历,然后找到所查询的歌曲信息,然后告诉用户,这里也需要合理性判断。

//查询
					struct song* p;
					p = head1;
					char arr[20];
					int flag = 0;
					if (p == NULL)
					{
						printf("还未有点播的歌曲\n");
						system("pause");
						system("cls");
						break;
					}
					printf("请输入要查询的歌曲名字(输入零退出):");
					scanf("%s", arr);
					while (arr[0] != '0')
					{
						p = head1;
						while (p->next != NULL)
						{			
							flag = 0;
							if (strcmp(p->song_name, arr) == 0)
							{
								flag = 1;
								break;
							}
							p = p->next;
						}
						if (flag == 0 && strcmp(p->song_name, arr) == 0)
						{
							flag == 1;
						}
						if (flag == 1)
						{
							printf("序号\t歌曲名称\n");
							printf("%d\t%-8s\n", p->num, p->song_name);
						}
						else
						{
							printf("未点播此歌曲\n");
						}
						printf("请输入要查询的歌曲名字(输入零退出):");
						scanf("%s", arr);
					}

因为考虑了用户可能需要多次查询,所以我就使用了循环来完成这个操作,同样地,输入‘0’时,结束查询。

3.3删除

删除地操作比较地复杂,基本上算是这个程序中比较难的一部分了。

删除地话,需要考虑删除的位置,不同地位置删除的方式不一样,并且例如要删除的链表中第一个和第二个节点,如果把第一个节点删除后,第二个节点就会变成第一个节点,那么还需要用删除第一个节点的方式来删除第二个节点,这种情况也是需要我们考虑的。

//删除
					int b = 0, flag = 0;
					if (head1 == NULL)
					{
						printf("还未有点播的歌曲\n");
						system("pause");
						system("cls");
						break;
					}
					pass(head1);
					printf("请选择要删除歌曲的序号(输入小于等于零结束):\n");
					scanf("%d", &b);
					while (b > 0)
					{
						struct song* p, * q;
						p = head1;//待删
						q = head1;//待删前一个
						while (p == head1)
						{
							//要删的是头节点
							if (p->num == b)
							{
								q = q->next;
								head1 = q;
								free(p);
								p = q;
								count1--;
							}
							else
								p = p->next;
						}
						while (p->next != NULL)
						{
							//删中间节点
							if (p->num == b)
							{

								q->next = p->next;
								free(p);
								p = q->next;
								count1--;
							}
							else
							{
								p = p->next;
								q = q->next;
							}
						}
						if (p->next == NULL)
						{
							//删尾节点
							if (p->num == b)
							{
								q->next = NULL;
								free(p);
								count1--;
							}
						}
						printf("请选择要删除歌曲的序号(输入小于等于零结束):\n");
						scanf("%d", &b);
					}

上面是删除的代码,下面我用简洁的方式来表示不同位置的不同删除方式:

C/C++对大一C语言的课程设计——KTV点歌系统的介绍(链表)_第2张图片

3.4置顶

置顶需要注意格式:

       在显示已点歌曲后,选择置顶歌曲的序号,将歌曲置顶,并重新排序列号。例如:“1.if you  2.红颜乱  3.凉凉”选择置顶歌曲:3.凉凉后,显示“1.凉凉 2.if you 3.红颜乱”;这不能是只将第一个节点的信息和要置顶的节点的信息交换,这类似于轮换的形式

struct song* top(struct song* head, int num)
{
	int my_count = 1;
	struct song* p, * q, * head1;
	head1 = NULL;
	p = head;//待置顶
	q = head;//待置顶前一个
	int flag = 0;
	if (num > count1 || num < 0)
		printf("点的歌单中暂无此歌曲\n");
	else
	{
		while (p->next != NULL)
		{
			if (p == head && p->num == num)
			{
				printf("此歌已置顶,请重新输入:\n");
				break;
			}
			else if (p->num == num && p != head)
			{
				q->next = p->next;
				p->next = head;
				head1 = p;
				flag = 1;
				my_count++;
				break;
			}
			else if (p == head && p->num != num)
				p = p->next;
			else
			{
				p = p->next;
				q = q->next;
			}
		}
		if (p->num == num && p != head && my_count != 2)
		{
			q->next = p->next;
			p->next = head;
			head = p;
			flag = 1;
			head1 = p;
		}
		if (flag == 1)
			return head1;
	}
}

3.5上移一位 

上移一位就是将要上移的节点和他前一个节点的信息进行交换就行(也就是把data里的数据进行交换)

struct song* ahead(struct song* head, int num)
{
	int flag = 0;
	struct song* p, * q, * head1 = NULL;
	char songname[20];
	char manname[20];
	p = head;//待前移
	q = head;//待前移的前一个
	if (num > count1 || num < 0)
		printf("点的歌单中暂无此歌曲\n");
	else
	{
		while (p->next != NULL)
		{
			if (p == head && p->num == num)
			{
				printf("已在最前面,无需前移\n");
				break;
			}
			else if (p != head && p->num == num)

			{
				strcpy(songname, p->song_name);
				strcpy(p->song_name, q->song_name);
				strcpy(q->song_name, songname);
				strcpy(manname, p->man_name);
				strcpy(p->man_name, q->man_name);
				strcpy(q->man_name, manname);
				head1 = p;
				flag = 1;
				break;
			}
			else if (p == head && p->num != num)
			{
				p = p->next;
			}
			else
			{
				p = p->next;
				q = q->next;
			}
		}
		if (flag == 0 && p->next && p->num == num)
		{
			strcpy(songname, p->song_name);
			strcpy(p->song_name, q->song_name);
			strcpy(q->song_name, songname);
			strcpy(manname, p->man_name);
			strcpy(p->man_name, q->man_name);
			strcpy(q->man_name, manname);
			head1 = p;
			flag = 1;
		}
		if (flag == 1)
		{
			return head1;
		}
	}
}

三、总代码

#include
#include
#include
int count = 0;//歌曲库中的歌曲数
int count1 = 0;//点歌的数量
struct song
{
	int num;
	char song_name[20];
	char man_name[10];
	struct song* next;
};
struct song* Initlinklist(); //初始化链表
int menu();//主菜单
int menu_first();//二级菜单-1
int menu_second();//二级菜单-2
struct song* songname_sort(struct song*);//按照歌曲名字排序
struct song* manname_sort(struct song*);//按照歌手名字排序
struct song* option(struct song*, struct song*);//点歌
void pass(struct song*);//遍历
struct song* top(struct song*, int);//置顶函数
struct song* ahead(struct song*, int);//上移一位
int main()
{
	struct song* head, * following, * s, * head1 = NULL;
	head = NULL;
	int i = 4;
	//初始化曲库
	head = Initlinklist();
	//菜单
	while (1)
	{
		int opt = menu();
		if (opt == 1)
		{
			//查看目前的歌曲库
			// 添加新曲库
			//遍历
			following = head;
			char song_name[20];
			char man_name[10];
			int num = 0;
			printf("序号\t歌曲名称\t歌手\n");
			while (following->next != NULL)
			{
				printf("%d\t%-8s\t%s\n", following->num, following->song_name, following->man_name);
				following = following->next;
			}
			printf("%d\t%-8s\t%s\n", following->num, following->song_name, following->man_name);
			printf("是否手动添加歌曲进入歌曲库(Yes(y)/NO(n)):\n");
			char Isright = ' ';
			while (1)
			{
				getchar();
				Isright = getchar();
				if (Isright == 'y')
				{
					printf("请添加歌曲名称、歌手\n");
					s = (struct song*)malloc(sizeof(struct song));
					num = i;
					scanf("%s", song_name);
					scanf("%s", man_name);
					s->num = num;
					strcpy(s->song_name, song_name);
					strcpy(s->man_name, man_name);
					i++;
					count++;
					s->next = following->next;
					following->next = s;
				}
				else
				{
					system("pause");
					system("cls");
					break;
				}
				printf("是否继续手动添加歌曲进入歌曲库(Yes(y)/NO(n)):\n");
			}
		}
		else if (opt == 2)
		{
			//点歌,二级菜单
			int flag = 1;
			while (1)
			{
				if (flag == 0)
					break;
				int ret1 = menu_first();
				following = head;
				if (ret1 == 1)
				{
					//按照歌曲库歌曲名字排序
					songname_sort(head);
					//遍历
					/*while (following->next != NULL)
					{
						printf("%d\t%-8s\t%s\n", following->num, following->song_name, following->man_name);
						following = following->next;
					}
					printf("%d\t%-8s\t%s\n", following->num, following->song_name, following->man_name);*/
					pass(head);
					flag = 0;
					head1 = option(head, head1);
					system("pause");
					system("cls");
				}
				else if (ret1 == 2)
				{
					//按照演唱者的名字排序
					manname_sort(head);
					//遍历
					/*while (following->next != NULL)
					{
						printf("%d\t%-8s\t%s\n", following->num, following->song_name, following->man_name);
						following = following->next;
					}
					printf("%d\t%-8s\t%s\n", following->num, following->song_name, following->man_name);*/
					pass(head);
					flag = 0;
					head1 = option(head, head1);
					system("pause");
					system("cls");
				}
				else if (ret1 == 0)
				{
					//合理性判断
					flag = 0;
					system("pause");
					system("cls");
					break;
				}
				else
				{
					printf("您输入的选项有误,请重新输入\n");
					system("pause");
					system("cls");

				}
			}
		}
		else if (opt == 3)
		{
			//已选歌单,二级菜单
			while (1)
			{
				int ret2 = menu_second();
				if (ret2 == 1)
				{
					//显示已点歌单---遍历head1
					struct song* p;
					p = head1;
					int a = 1;
					if (p == NULL)
					{
						printf("还未有点播的歌曲\n");
						system("pause");
						system("cls");
						break;
					}
					printf("序号\t歌曲名称\t歌手\n");
					while (p->next != NULL)
					{
						p->num = a;
						printf("%d\t%-8s\t%s\n", p->num, p->song_name, p->man_name);
						p = p->next;
						a++;
					}
					p->num = a;
					printf("%d\t%-8s\t%s\n", p->num, p->song_name, p->man_name);
					system("pause");
					system("cls");
				}
				else if (ret2 == 2)
				{
					//查询
					struct song* p;
					p = head1;
					char arr[20];
					int flag = 0;
					if (p == NULL)
					{
						printf("还未有点播的歌曲\n");
						system("pause");
						system("cls");
						break;
					}
					printf("请输入要查询的歌曲名字(输入零退出):");
					scanf("%s", arr);
					while (arr[0] != '0')
					{
						p = head1;
						while (p->next != NULL)
						{
							flag = 0;
							if (strcmp(p->song_name, arr) == 0)
							{
								flag = 1;
								break;
							}
							p = p->next;
						}
						if (flag == 0 && strcmp(p->song_name, arr) == 0)
						{
							flag == 1;
						}
						if (flag == 1)
						{
							printf("序号\t歌曲名称\n");
							printf("%d\t%-8s\n", p->num, p->song_name);
						}
						else
						{
							printf("未点播此歌曲\n");
						}
						printf("请输入要查询的歌曲名字(输入零退出):");
						scanf("%s", arr);
					}
					system("pause");
					system("cls");
				}
				else if (ret2 == 3)
				{
					//删除
					int b = 0, flag = 0;
					if (head1 == NULL)
					{
						printf("还未有点播的歌曲\n");
						system("pause");
						system("cls");
						break;
					}
					pass(head1);
					printf("请选择要删除歌曲的序号(输入小于等于零结束):\n");
					scanf("%d", &b);
					while (count1 > 0 && b > 0)
					{
						struct song* p, * q;
						p = head1;//待删
						q = head1;//待删前一个
						if (p != NULL && p == head1)
						{
							//要删的是头节点
							if (p->num == b)
							{
								q = q->next;
								head1 = q;
								free(p);
								p = q;
								count1--;
							}
							else
								p = p->next;
						}
						if (p != NULL && p->next != NULL)
						{
							//删中间节点
							if (p->num == b)
							{

								q->next = p->next;
								free(p);
								p = q->next;
								count1--;
							}
							else
							{
								p = p->next;
								q = q->next;
							}
						}
						if (p != NULL && p->next == NULL)
						{
							//删尾节点
							if (p->num == b)
							{
								q->next = NULL;
								free(p);
								count1--;
							}
						}
						printf("请选择要删除歌曲的序号(输入小于等于零结束):\n");
						scanf("%d", &b);
					}
					printf("\n");
					pass(head1);
					system("pause");
					system("cls");
				}
				else if (ret2 == 4)
				{
					//置顶
					struct song* p;//要置顶的歌曲
					int num;
					if (head1 == NULL)
					{
						printf("还未有点播的歌曲\n");
						system("pause");
						system("cls");
						break;
					}
					pass(head1);
					printf("请选择要置顶的歌曲序号(输入零结束):");
					scanf("%d", &num);
					while (num != 0)
					{
						head1 = top(head1, num);
						printf("\n");
						pass(head1);
						system("pause");
						system("cls");
						printf("请选择要置顶的歌曲序号(输入零结束):");
						scanf("%d", &num);
					}
				}
				else if (ret2 == 5)
				{
					//上移一位
					int num;
					if (head1 == NULL)
					{
						printf("还未有点播的歌曲\n");
						system("pause");
						system("cls");
						break;
					}
					pass(head1);
					printf("请输入要上移一位歌曲的序号\n");
					scanf("%d", &num);
					ahead(head1, num);
					pass(head1);
					system("pause");
					system("cls");
				}
				else if (ret2 == 0)
				{
					//退出
					system("pause");
					system("cls");
					break;
				}
				else
				{
					//合理性判断
					printf("选择错误,请重新选择\n");
					system("pause");
					system("cls");
				}
			}
		}
		else if (opt == 0)
		{
			break;
		}
		else
		{
			printf("您输入的选项有误,请重新输入:\n");
			system("pause");

			system("cls");
		}
	}
	return 0;
}
void pass(struct song* head)
{
	struct song* p;
	p = head;
	int i = 1;
	if (p == NULL)
	{
		printf("暂无点歌\n");
	}
	else
	{
		while (p->next != NULL)
		{
			p->num = i;
			printf("%d\t%-8s\t%s\n", p->num, p->song_name, p->man_name);
			p = p->next;
			i++;
		}
		p->num = i;
		printf("%d\t%-8s\t%s\n", p->num, p->song_name, p->man_name);
	}
}
int menu()
{
	printf("##################################\n");
	printf("#      1.查看目前的歌曲库^       #\n");
	printf("#      2.点歌^                   #\n");
	printf("#      3.已点歌曲^               #\n");
	printf("#      0.退出                    #\n");
	printf("##################################\n");
	printf("请输入选项:");
	int opt;
	scanf("%d", &opt);
	return opt;
}
struct song* Initlinklist()
{
	struct song* head, * s, * tail;
	head = NULL;
	s = (struct song*)malloc(sizeof(struct song));
	s->num = 1;
	strcpy(s->song_name, "左手右手");
	strcpy(s->man_name, "郭子荷");
	s->next = NULL;
	head = s;
	tail = s;
	s = s->next;
	s = (struct song*)malloc(sizeof(struct song));
	s->num = 2;
	strcpy(s->song_name, "红颜乱");
	strcpy(s->man_name, "刘涛");
	tail->next = s;
	tail = tail->next;
	s = (struct song*)malloc(sizeof(struct song));
	s->num = 3;
	strcpy(s->song_name, "凉凉");
	strcpy(s->man_name, "张碧晨");
	s->next = NULL;
	tail->next = s;
	tail = tail->next;
	count = 3;
	return head;
}
int menu_first()
{
	int opt = 0;
	printf("########################################\n");
	printf("#    1)按照歌曲库中歌曲拼音字母排序   #\n");
	printf("#    2)按照演唱者名字首拼音字母排序   #\n");
	printf("#    0)退出                           #\n");
	printf("########################################\n");
	printf("请选择选项\n");
	scanf("%d", &opt);
	return opt;
}
int menu_second()
{
	int opt = 0;
	printf("################################\n");
	printf("#    1)显示已点歌单           #\n");
	printf("#    2)查询歌曲               #\n");
	printf("#    3)删除歌曲               #\n");
	printf("#    4)置顶歌曲               #\n");
	printf("#    5)上移一位               #\n");
	printf("#    0)退出                   #\n");
	printf("################################\n");
	printf("请选择选项\n");
	scanf("%d", &opt);
	return opt;
}
struct song* songname_sort(struct song* head)
{
	struct song* p;
	p = head;
	int i = 0, flag = 0;
	char song_name[20];
	char man_name[20];
	for (i; i < count; i++)
	{
		p = head;
		while ((p->next)->next != NULL)
		{
			if (strcmp(p->song_name, (p->next)->song_name) == 1)
			{
				strcpy(song_name, p->song_name);
				strcpy(p->song_name, (p->next)->song_name);
				strcpy((p->next)->song_name, song_name);
				strcpy(man_name, p->man_name);
				strcpy(p->man_name, (p->next)->man_name);
				strcpy((p->next)->man_name, man_name);
			}
			p = p->next;
		}
		if (strcmp(p->song_name, (p->next)->song_name) == 1)
		{
			strcpy(song_name, p->song_name);
			strcpy(p->song_name, (p->next)->song_name);
			strcpy((p->next)->song_name, song_name);
			strcpy(man_name, p->man_name);
			strcpy(p->man_name, (p->next)->man_name);
			strcpy((p->next)->man_name, man_name);
		}
	}
	return head;
}
struct song* manname_sort(struct song* head)
{
	struct song* p;
	p = head;
	int i = 0, flag = 0;
	char song_name[20];
	char man_name[20];
	for (i; i < count; i++)
	{
		p = head;
		while ((p->next)->next != NULL)
		{
			if (strcmp(p->man_name, (p->next)->man_name) == 1)
			{
				strcpy(song_name, p->song_name);
				strcpy(p->song_name, (p->next)->song_name);
				strcpy((p->next)->song_name, song_name);
				strcpy(man_name, p->man_name);
				strcpy(p->man_name, (p->next)->man_name);
				strcpy((p->next)->man_name, man_name);
			}
			p = p->next;
		}
		if (strcmp(p->man_name, (p->next)->man_name) == 1)
		{
			strcpy(song_name, p->song_name);
			strcpy(p->song_name, (p->next)->song_name);
			strcpy((p->next)->song_name, song_name);
			strcpy(man_name, p->man_name);
			strcpy(p->man_name, (p->next)->man_name);
			strcpy((p->next)->man_name, man_name);
		}
	}
	return head;
}
struct song* option(struct song* head, struct song* head1)
{
	struct song* s, * p, * tail;
	s = head;
	p = head1;
	tail = head1;
	int num, i = 1, index = 0;
	char song_name[20];
	char man_name[10];
	printf("请输入想选的歌曲序号(输入零结束):");
	scanf("%d", &num);
	while (num != 0)
	{
		s = head;
		if (num > count || num < 0)
		{
			printf("查无此序号歌曲,请重新输入:");
			scanf("%d", &num);
			continue;
		}
		int a = 1;
		for (i = 1; i <= count; i++)
		{
			if (s->num == num)
			{
				p = (struct song*)malloc(sizeof(struct song));
				p->num = a;
				strcpy(p->song_name, s->song_name);
				strcpy(p->man_name, s->man_name);
				if (head1 == NULL)
				{
					head1 = p;
					p->next = NULL;
					tail = p;
				}
				else
				{
					p->next = tail->next;
					tail->next = p;
					tail = tail->next;
				}
			}
			s = s->next;
			a++;
		}
		index = num;
		count1++;
		printf("请输入想选的歌曲序号(输入零结束):");
		scanf("%d", &num);
	}
	return head1;
}
struct song* top(struct song* head, int num)
{
	int my_count = 1;
	struct song* p, * q, * head1;
	head1 = NULL;
	p = head;//待置顶
	q = head;//待置顶前一个
	int flag = 0;
	if (num > count1 || num < 0)
		printf("点的歌单中暂无此歌曲\n");
	else
	{
		while (p->next != NULL)
		{
			if (p == head && p->num == num)
			{
				printf("此歌已置顶,请重新输入:\n");
				break;
			}
			else if (p->num == num && p != head)
			{
				q->next = p->next;
				p->next = head;
				head1 = p;
				flag = 1;
				my_count++;
				break;
			}
			else if (p == head && p->num != num)
				p = p->next;
			else
			{
				p = p->next;
				q = q->next;
			}
		}
		if (p->num == num && p != head && my_count != 2)
		{
			q->next = p->next;
			p->next = head;
			head = p;
			flag = 1;
			head1 = p;
		}
		if (flag == 1)
			return head1;
	}
}
struct song* ahead(struct song* head, int num)
{
	int flag = 0;
	struct song* p, * q, * head1 = NULL;
	char songname[20];
	char manname[20];
	p = head;//待前移
	q = head;//待前移的前一个
	if (num > count1 || num < 0)
		printf("点的歌单中暂无此歌曲\n");
	else
	{
		while (p->next != NULL)
		{
			if (p == head && p->num == num)
			{
				printf("已在最前面,无需前移\n");
				break;
			}
			else if (p != head && p->num == num)

			{
				strcpy(songname, p->song_name);
				strcpy(p->song_name, q->song_name);
				strcpy(q->song_name, songname);
				strcpy(manname, p->man_name);
				strcpy(p->man_name, q->man_name);
				strcpy(q->man_name, manname);
				head1 = p;
				flag = 1;
				break;
			}
			else if (p == head && p->num != num)
			{
				p = p->next;
			}
			else
			{
				p = p->next;
				q = q->next;
			}
		}
		if (flag == 0 && p->next && p->num == num)
		{
			strcpy(songname, p->song_name);
			strcpy(p->song_name, q->song_name);
			strcpy(q->song_name, songname);
			strcpy(manname, p->man_name);
			strcpy(p->man_name, q->man_name);
			strcpy(q->man_name, manname);
			head1 = p;
			flag = 1;
		}
		if (flag == 1)
		{
			return head1;
		}
	}
}

谢谢大家

你可能感兴趣的:(小项目,c语言)