本文将单链表与双向链表的基本操作在同一个程序中实现。其中单链表头文件中的函数与双向链表头文件中的函数可以分离出来单独使用。菜单程序的实现的程序较为复杂,变量多且作用范围不同,如果修改代码需要对代码非常熟悉,没有很好的做到函数的可分离。见谅!
完整头文件和代码下载链接请拉到最底端!
一、菜单功能及从属关系
注意:
1.程序设置了两个单链表节点指针和两个双向链表节点指针,但是表现给使用者的链表数同时间内最多两条,最少0条。(用n作为操作数来提示使用者创建链表的情况)n=n1+n2;例如若我创建链表1为单链表,链表2为双向链表,则n=12
2.进行每一项操作前,程序都需要确认进行操作的是哪一条链表,本质是确认该链表的类型是单链表还是双向链表还是未生成(NULL)。
3.第一层菜单是链表层面的操作,第二层菜单是节点层面的操作。
二、代码实现
1.单链表基本操作的头文件
头文件:linkedList.h
详情请见这篇blog。
《单链表基本函数头文件》https://blog.csdn.net/weixin_45849757/article/details/107434829
2.双向链表基本操作的头文件
头文件:duLinkedList.h
详情见这篇blog。
《双向链表基本函数头文件》
https://blog.csdn.net/weixin_45849757/article/details/107447269
3.基本操作实现
头文件+声明
#include"duLinkedList.h"
#include"linkedList.h"
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>
#define NUL '\0'
LNode*head1=NULL; //单链表a
LNode*head2=NULL; //单链表b
DuLNode*head3=NULL; //双向链表c
DuLNode*head4=NULL; //双向链表d
static int n; //操作数记录链表状态
/*函数声明*/
void welcome(); //主菜单
void Create(); //创建链表菜单
void Single(int link); //创建单链表
void Double(int link); //创建双向链表
void Destroy(); //销毁链表菜单
void ClearList(); //清零链表内容
void Choose(); //选择链表函数
void Print(); //打印链表内容
void Enter(); //输入数据
DuLNode* DuLinkedList_Menu(DuLNode*p);//双向链表节点操作菜单
LNode* LinkedList_Menu(LNode*p);//单链表节点操作菜单
void Other();//跳转至节点菜单的函数
void RanklinkedList(LinkedList*L,int n); //单链表排序(后续会包含到头文件里)
void SwaplinkedList(LNode* p,LNode* q); //交换p后和q后一结点的位置(后续会包含到头文件里)
void Merge();//合并链表操作
void MergelinkedList(LNode* head1,LNode* head2); //合并单链表的函数(后续会包含到头文件里)
void MergelinkedList_Dul(DuLNode* head1,DuLNode* head2);//合并双向链表(后续会包含到头文件)
主函数
void main()
{
system("title 链表练习 —— 刘欣羽");//设置标题
welcome();
system("pause");
}
主菜单
1.功能界面
2.提示使用者链表的创建情况。
void welcome()
{
int choice;
A:system("cls");
printf(" 主菜单\n");
printf(" -----------------------------------------------------------------------\n");
printf("*****************************************************************************\n");
printf("\n");
printf(" 1---创建链表 2---销毁链表\n");
printf("\n");
printf(" 3---输入数据 4---清零链表 \n");
printf("\n");
printf(" 5---打印链表 6---其他操作\n");
printf("\n");
printf(" 7---合并链表 8---退出菜单\n");
printf("\n");
printf("*****************************************************************************\n");
printf(" -----------------------------------------------------------------------\n");
if(n==0)
printf("提示:你一共可以创建两条链表 链表1:未创建 链表2:未创建\n");
else if(n<10)
printf("提示:你一共可以创建两条链表 链表1:未创建 链表2:已创建\n");
else if(n==n/10*10)
printf("提示:你一共可以创建两条链表 链表1:已创建 链表2:未创建\n");
else
printf("提示:你一共可以创建两条链表 链表1:已创建 链表2:已创建\n");
printf("\n");
printf("请输入序号:\n");
fflush(stdin);
scanf("%d",&choice);
switch(choice)
{
case 1:Create();goto A;
case 2:Destroy(); goto A;
case 3:Enter();goto A;
case 4:ClearList(); goto A;
case 5:Print();goto A;
case 6:Other();goto A;
case 7:Merge();goto A;
case 8:DestroyList(&head1);DestroyList(&head2);DestroyList_DuL(&head3);DestroyList_DuL(&head4);break;
default:printf("error\n");goto A;
}
return;
}
创建链表
1.在此界面上选择链表的创建内容
void Create()
{
int choice;
int link;
A:system("cls");
printf(" -----------------------------------------------------------------------\n");
printf("*****************************************************************************\n");
printf("\n");
printf(" 1---单链表 2---双向链表 3---退出\n");
printf("\n");
printf("*****************************************************************************\n");
printf(" -----------------------------------------------------------------------\n");
printf("请输入序号:\n");
fflush(stdin);
scanf("%d",&choice);
if(choice==3)goto B;
if(choice!=1&&choice!=2)
{
printf("输入有误!\n");
system("pause");
goto A;
}
printf("请输入需要生成链表代号 1/2:\n");
fflush(stdin);
scanf("%d",&link);
if (link!=1&&link!=2)
{
printf("代号有误\n");system("pause");return;
}
if((n>=10&&link==1)||(n>0&&n<10&&link==2))
{
printf("无法新增链表\n");
system("pause");
return;
}
switch(choice)
{
case 1:Single(link);break;
case 2:Double(link);break;
case 3:break;
default:printf("error\n");system("pause");goto A;
}
B: return;
}
创建单链表
void Single(int link)
{
int i;
LNode*head,*p,*q;
A:printf("请输入链表长度\n");
fflush(stdin);
scanf("%d",&i);
if(i<=0)
{
printf("请输入大于1整数!\n");
goto A;
}
head=(LinkedList)malloc(sizeof(LNode));
q=head;
q->data=0;
q->next=NULL;
for (int j=1;j<i;j++)
{
if(InitList(&p)==1)
{
q->next=p;
q=q->next;
q->data=j;
}
else
{
printf("生成新节点过程出错\n"); //不足:已生成结点需要删掉 引用删除函数
return;
}
}