18.12.22
在计算机中用一组地址连续的存储单元依次存储线性表的各个数据元素,称作线性表的顺序存储结构.
顺序存储结构是存储结构类型中的一种,该结构是把逻辑上相邻的节点存储在物理位置上相邻的存储单元中,结点之间的逻辑关系由存储单元的邻接关系来体现。由此得到的存储结构为顺序存储结构,通常顺序存储结构是借助于计算机程序设计语言(例如c/c++)的数组来描述的。
顺序存储结构的主要优点是节省存储空间,因为分配给数据的存储单元全用存放结点的数据(不考虑c/c++语言中数组需指定大小的情况),结点之间的逻辑关系没有占用额外的存储空间。采用这种方法时,可实现对结点的随机存取,即每一个结点对应一个序号,由该序号可以直接计算出来结点的存储地址。但顺序存储方法的主要缺点是不便于修改,对结点的插入、删除运算时,可能要移动一系列的结点。
优点:随机存取表中元素。缺点:插入和删除操作需要移动元素。
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 1024//定义顺序表的最大长度
#define TRUE 1
#define FALSE 0
typedef int datatype;定义int的别名,或#define datatype int
typedef struct
{
datatype elem[MAXSIZE];
int length; //表长
}SeqList; //定义顺序表抽象数据类型
void init_List(SeqList *L)//顺序表的初始化
{
L->length = 0;
}
void creat_List(SeqList *L)//创建顺序表
{
int i;
printf("请输入顺序表长度:\n");
scanf("%d",&L->length);
printf("请输入顺序表元素:\n");
for(i = 0;i < L->length;i++)
{
scanf("%d",&L->elem[i]);
}
}
void clear_List(SeqList *L)//清空顺序表
{
L->length = 0;
}
int loc_List(SeqList *L,int local)//顺序表的按值查找
{
int i = 0;
if(L->length == 0)//空表
return FALSE;
for(i = 0;i < L->length;i++)
{
if(L->elem[i] == local)//找到local
return i+1;//返回找到local的位置
}
return 0;//遍历完顺序表没找到
}
int ins_List(SeqList *L,int i,int data)//顺序表中第i个位置插入数据
{
int j;//数据次序
printf("在第%d个位置上插入数据%d\n",i,data);
if(L->length == MAXSIZE)//原顺序表已满
{
printf("overflow\n");
return FALSE;//溢出
}
if(i < 1 || i > L->length)//位置不合适及检查是否为空表
{
printf("error,please input the right i\n");//有返回值的函数也可以输出
return FALSE;
}
for(j = L->length;j >= i;j--)//第i-1个位置之后的数据都后移一位
{
L->elem[j] = L->elem[j-1];
}
L->elem[i-1] = data;
L->length++;//表长加一
return TRUE;
}
int del_List(SeqList *L,int i) //顺序表中删除第i个数据
{
int j; //数据次序
printf("删除第%d个位置上的数据\n");
if(i < 1 || i > L -> length)
return FALSE;
for(j = i;j < L -> length;j++)
{
L -> elem[j-1] = L -> elem[j];//第i个位置之后的数据都前移一个位置
}
L->length--;//表长减一
return TRUE;
}
void print_List(SeqList *L)//输出顺序表
{
int i;
if(L->length == 0)//判断空表
printf("表为空\n");
for(i = 0;i < L->length ;++i)
{
printf("%d ",L->elem[i]);
}
printf("\n");
}
void menu(void)//菜单函数
{
printf("\t\t***************顺序表的查找、插入、删除***************\n");//菜单
printf("\t\t|| a. 建立一个顺序表 ||\n");//\t的作用是跳格,即跳到下一个“制表位置”(也有说是TAB位置),在我们所用的系统中一个“制表区”占8列。“下一制表位置”从第9列开始,
printf("\t\t|| b. 顺序表中按值查找 ||\n");
printf("\t\t|| c. 在顺序表中第i个位置插入一个元素 ||\n");
printf("\t\t|| d. 删除在顺序表中第i个位置的元素 ||\n");
printf("\t\t|| e. 输出顺序表中的所有元素 ||\n");
printf("\t\t|| f. 清空顺序表 ||\n");
printf("\t\t|| q. 退出程序 ||\n");
printf("\t\t******************************************************\n");
}
char menu_select(void)//菜单功能选择函数
{
char cmd;
printf("\n请输入您选择功能的序号(a~e):\n");
cmd = getchar();
while((cmd > 'a' && cmd < 'f') || (cmd == 'q'))
return cmd;
}
main() //省略情况,默认为 int main()
{
SeqList *L;
int i,local,data;
char cmd;
L = (SeqList *)malloc(sizeof(SeqList));//分配动态存储空间,创建顺序表;
menu();
do
{
cmd = 0;//初始化
switch(menu_select())//菜单选择,调用menu_select函数(printf语句实现,返回字符)
{
case 'a':
printf("\t\t****************建立一个顺序表************************\n");
creat_List(L);
getchar();//清除输入缓冲区的回车符
break;
case 'b':
printf("\t\t****************在顺序表中按值查找********************\n");
printf("请输入需要查找的值:\n");
scanf("%d",&local);
printf("输出需要查找的值的位置i:\n");
printf("%d\n",loc_List(L,local));
fflush(stdin);//清除标准输入缓冲区。相当于getchar()清除输入缓冲区的回车符
break;
case 'c':
printf("\t\t************在顺序表中第i个位置插入一个元素***********\n");
printf("请输入需要插入的位置i和数据:\n");
scanf("%d%d",&i,&data);
ins_List(L,i,data);
getchar();
break;
case 'd':
printf("\t\t************删除在顺序表中第i个位置的元素*************\n");
printf("请输入需要删除的位置i:\n");
scanf("%d",&i);
del_List(L,i);
getchar();
break;
case 'e':
printf("\t\t****************输出顺序表中的所有元素****************\n");
printf("输出顺序表所有元素:\n");
print_List(L);
getchar();
break;
case 'f':
printf("\t\t**********************清空顺序表**********************\n");
clear_List(L);
getchar();
break;
case 'q':
printf("\t\t***********************谢谢使用***********************\n");
cmd = 'q';
break;
}
}while(cmd != 'q');
}