本片博客,以代码为主
一、代码
再写代码之前先来了解一下,线性结构的特点和定义的几个顺序链表基本操作
线性结构的特点
顺序链表基本操作
1:初始化顺序链表
2:插入顺序链表
3:判断当前顺序链表是否为空
4:清空顺序链表
5:打印顺序链表中的元素
6:当前顺序链表元素个数
代码
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 20 //定义数组多大长度
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int ElemType;
typedef int Status;
typedef struct{
ElemType data[MAXSIZE];
int lenght;
}Sqlist;//定义顺序链表结构
int printMenu(void);
Status initList(Sqlist *L);
Status ListInsert(Sqlist *L);
void PleaseInit(void);
Status PrintElement(const Sqlist *L);
Status IsEmpty(const Sqlist *L);
Status ClearList(Sqlist *L);
int main(int argc, char *argv[]) {
int menuChoice,index;
Sqlist list;
list.lenght=0;//初始化
while(menuChoice=printMenu())
{
switch(menuChoice)
{
case 1:
initList(&list);
break;
case 2:
ListInsert(&list);
break;
case 3:
IsEmpty(&list);
break;
case 4:
ClearList(&list);
break;
case 5:
PrintElement(&list);
break;
case 6:
ListLenght(&list);
break;
}
}
return 0;
}
//打印菜单
int printMenu(void)
{
int choice;
printf("*******顺序链表练习*******\n");
printf("1:初始化顺序链表\n");
printf("2:插入顺序链表\n");
printf("3:判断当前顺序链表是否为空\n");
printf("4:清空顺序链表\n");
printf("5:打印顺序链表中的元素\n");
printf("6:当前顺序链表元素个数\n");
printf("按下0退出程序\n");
printf("**************************\n");
printf("请选择:");
scanf("%d",&choice);
return choice;
}
//1初始化
Status initList(Sqlist *L)
{
int inputSize,i;
printf("当前选的为--1:初始化顺序链表--\n");
printf("请输入初始化链表大小(1-10):");//
scanf("%d",&inputSize);
if(L->lenght!=0)
{//判断当前顺序链表是否为空
printf("当前顺序链表不为空!请先删除链表元素,再进行初始化。\n\n");
return ERROR;
}
if(inputSize>10&inputSize<1)
{
printf("输入错误!\n");
return ERROR;
}
if(inputSize>MAXSIZE||inputSize<1)
{//判断输入是否超过链表范围
printf("输入错误!已退出程序");
return ERROR;
}else{
printf("请输入%d个元素:",inputSize);
L->lenght=inputSize;//存入当前顺序链表长度
for(i=0;i<inputSize;i++)
scanf("%d",&L->data[i]);
}
printf("你输入的数值为:");
for(i=0;i<L->lenght;i++)
printf("%5d",L->data[i]);
printf("\n");
return OK;
}
//2插入顺序链表
Status ListInsert(Sqlist *L)
{//index -元素下标,element-要插入元素
int index,element,i;
printf("当前选的为--2:插入顺序链表--\n");
if(L->lenght==0)
{
PleaseInit();
return ERROR;
}
printf("请输入要插入的位置:");
scanf("%d",&index);
printf("请输入要插入的元素:");
scanf("%d",&element);
if(index<1||index>L->lenght||L->lenght>=MAXSIZE)
{
printf("插入错误\n");
return ERROR;
}
if(index<=L->lenght)
{
for(i=L->lenght;i>=index;i--)
{
L->data[i]=L->data[i-1];
}
}
L->data[i]=element;
L->lenght++;
printf("在%d位置,插入%d成功!\n",index,element);
return OK;
}
//3:判断当前顺序链表是否为空
Status IsEmpty(const Sqlist *L)
{
printf("当前选的为--3:判断当前顺序链表是否为空--\n");
if(L->lenght==0)
{
printf("当前链表为空\n");
PleaseInit();
return ERROR;
}else{
printf("当前链表为不空\n");
return OK;
}
}
//4:清空顺序链表
Status ClearList(Sqlist *L)
{
char inputChar;
printf("当前选的为--4:清空顺序链表--\n");
if(L->lenght==0)
{
PleaseInit();
return ERROR;
}
printf("是否清空顺序链表?(Y/N):");
scanf(" %c",&inputChar);//注意%c前面加空格,这样c才不会接受到空格
switch(inputChar)
{
case 'Y':
case 'y':
L->lenght=0;
printf("清空成功!\n");
return OK;
break;
case 'N':
case 'n':
return FALSE;
break;
}
return OK;
}
//5:打印顺序链表中的元素
Status PrintElement(const Sqlist *L)
{
int i;
printf("当前选的为--5:打印顺序链表中的元素--\n");
if(L->lenght==0)
{
PleaseInit();
return ERROR;
}
for(i=0;i<L->lenght;i++)
printf("%2d",L->data[i]);
printf("\n");
return OK;
}
//6获取当前顺序链表元素个数
Status ListLenght(const Sqlist *L)
{
printf("当前选的为--6:当前顺序链表元素个数--\n");
if(L->lenght==0)
{
PleaseInit();
return ERROR;
}else{
printf("当前顺序链表元素个数为:%d个\n",L->lenght);
}
return OK;
}
//请先初始化样式
void PleaseInit(void)
{
printf("**************\n");
printf("*请先初始化 *\n");
printf("**************\n\n");
}
删除操作和插入操作相反,这里就没有再写
运行结果图
1.初始化
6.当前顺序链表元素个数
5:打印顺序链表中的元素
2:插入顺序链表并输出链表的元素
可以发现在3后面(也就是之前4的位置)插入了6
3:判断当前顺序链表是否为空
4:清空顺序链表并判断当前链表是否为空
二、顺序链表的优缺点
优点:①:无须为表示表中的元素之间的逻辑关系而增加额外的存储空间
②:可以快速地存取表中任一位置的元素,因为它的时间复杂度为O(1).注:本片代码没有写指定位置的存取操作
缺点:①:插入和删除操作需要移动大量元素
②:当线性表长度变化比较大时,难以确定存储空间的容量
③:造成存储空间的碎片