目录:
1.头文件
2.单链表的定义
3.菜单栏的设置
4.单链表的初始化
5.添加元素
6.打印元素
7.插入元素
8.删除元素
9.主函数
1.头文件
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef int ElemType;
typedef struct node;
void menu();
LinkList init();//初始化链表
void add(LinkList L);//添加元素
void print(LinkList L);//打印元素
void insert(LinkList L);//插入元素
void delete(LinkList L);//删除元素
2.单链表的定义
typedef struct LNode
{
ElemType data;//结点的数据域
struct LNode* next;//结点的指针域
int n;
}LNode,*LinkList;//LinkList为指向结构体LNode的指针类型
LinkList L;//L为单链表的头指针
3.菜单栏的设置
void menu()
{
{
int option;
printf("----链表的基本操作---\n");
printf("----0.初始化顺序表----\n");
printf("----1.添加元素--------\n");
printf("----2.打印元素--------\n");
printf("----3.删除元素--------\n");
printf("----4.插入元素--------\n");
printf("----------------------\n");
printf("请输入选择的操作:");
scanf_s("%d", &option);
switch (option)
{
case 0:
L=init();
break;
case 1:
add(L);
break;
case 2:
print(L);
break;
case 3:
delete(L);
break;
case 4:
insert(L);
break;
default:
printf("你选择的菜单项不存在,请重新选择\n");
}
system("pause");//暂停,不然控制台程序会一闪即过,你来不及看到执行结果
//system("cls");
}
}
4.单链表的初始化
LinkList init()
{
printf("********初始化单链表********\n");
LinkList L = (LinkList)malloc(sizeof(LNode));//生成新结点作为头结点,用头指针L指向头结点
L->next = NULL;//头结点的指针域置空
printf("链表初始化成功!\n");
//system("pause");//暂停,不然控制台程序会一闪即过,你来不及看到执行结果
//system("cls");清屏
return L;
//LinkList与*LNode本质上是等价的,若定义LinkList L,则L为单链表的头指针,若定义LNode *p,则p为指向单链表中某个结点的指针,*p代表该结点。
}
5.添加元素
void add(LinkList L)
{
int m, x;
LNode* p;//p为指向单链表中某个结点的指针
p = L->next;//初始化,p指向首元结点
printf("********添加元素********\n");
printf("请输入要添加元素的个数:");
scanf("%d", &m);
for (int i = 1; i <= m; i++)
{
p = (LNode*)malloc(sizeof(LNode));//初始化
printf("请输入第%d个元素的值:",i);
scanf("%d", &x);
p->data= x;//将插入元素的数据域存放在p中
p ->next = L->next;//将p的指针域指向下一个结点
L->next = p;//使头结点指向的下一个结点是p
L->n++;
printf("恭喜您,添加成功");
}
system("cls");//清屏
}
6.打印元素
void print(LinkList L)
{
printf("********打印元素********");
LNode* p;//p为指向单链表中某个结点的指针
p = L->next;//初始化,p指向首元结点
while (p)//直到最后一个结点后停止
{
printf("%d ", p->data);
p = p->next;//使p指向下一个结点
}
printf("\n");
}
7.插入元素
void insert(LinkList L)
{
LNode* p,*q;//p为指向单链表中某个结点的指针
int x, y,i;
printf("********插入元素********\n");
printf("请输入插入元素的个数:");
scanf("%d", &x);
for (int s = 0; s < x; s++)
{
int j = 0;
p = L->next;//初始化p,使p指向首元结点
printf("请输入要插入元素的位置:");
scanf("%d", &i);
printf("请输入要插入元素的数据域:");
scanf("%d", &y);
while(p&&(j<i-1))//直到p为空(最后一个元素的数据域为空)或p指向第i个元素
{
p = p->next;//查找第i-1个结点,p指向该结点
++j;
}
if (!p || j>i-1)//若p为空,意思是指向了最后一个元素或是输入的位置不合法
{
printf("您输入的位置不合法\n");
}
else
{
q = (LNode*)malloc(sizeof(LNode));//为新节点开辟地址
q->data = y;//将输入的值赋给q
q->next = p->next;//将*q的指针域指向下一个结点
p->next = q;//使p指向q
printf("插入成功\n");
}
}
}
8.删除元素
void delete(LinkList L)
{
printf("********删除元素********\n");
printf("请输入要删除的位置:");
int i;
scanf("%d", &i);
LNode* p;//指针p指向当前扫描到的结点
int j = 0;//当前p指向的是第几个结点
p = L;//L指向头结点,头结点是第0个结点(不存储数据)
while (p != NULL && j < i - 1)//循环找到第i-1个结点
{
p = p->next;
++j;
}
if (!p || j > i - 1)
{
printf("您输入的位置已越界\n");
}
else
{
LNode* q = p->next;//令q指向被删除结点
p->next = q->next;//将p结点的指针域直接指向被删除的下一个结点
free(q);//删除结点
printf("删除成功\n");
}
}
9.主函数
int main()
{
while(1)
{
menu();
}
return 0;
}
注意:链表和顺序表不同,链表中逻辑相邻的结点并没有在存储在物理相邻的单元中,这样,根据给定的结点位置序号i,在链表中获取该结点的值不能像顺序表那样随机访问,而只能从链表的首元素结点出发,顺着链域next逐个结点向下访问。因此,需要用while循环来找到该结点