线性表
一、线性表的基本概率
1、线性表的定义
线性表是具有相同数据类型的n(n>= 0)个数据元素的有限序列。
2、线性表举例
(1)简单的线性表。例如,26个英文字母表;一周七天。
(2)复杂的线性表。例如,学生信息登记表。
在复杂的线性表,常把数据元素称为记录(Record),它由若干个数据项(Item)组成,而含有大量记录的线性表又称为文件(File)。
3、线性表的特点
(1)有且仅有一个开始结点,它没有直接前驱。
(2)有且仅有一个终端结点,它没有直接后继。
(3)除了开始结点和终端结点外,其余的结点都有且仅有一个直接前驱和一个直接后继。
4、线性表的基本操作
(1)初始化线性表InitList(L)
初始条件:表不存在。
操作结果:其作用是建立一个空表L(即建立线性表的框架,但不包括任何数据元素)。
(2)求线性表的长度GetLength(L)
初始条件:表不存在。
操作结果:其作用是返回线性表L的长度(即所含数据元素的个数)
(3)按位置查找操作GetElem(L,i,x).
初始条件:线性表L存在,i是表中元素位置,x是找到该元素返回的值。
操作结果:在线性表L查找第i是表中元素位置,其作用是若第i位上有数据元素,则由x传回该元素值,返回1:若不存在返回0.
(4)按值查找操作Locate(L,x)
初始条件:线性表L存在,x是给它的一个待查数据元素。
操作结果:在线性表L查找一个与给定值x相等的数据元素,其作用是若存在一个或多个与x相等的数据元素,则返回元素所在位置的最小值或地址值:否则返回0或NULL值。
(5)插入操作InsElem(L,i,x)。
初始条件:线性表L存在且插入位置正确(1<=i<=n+1,n为插入前表的长度)。
操作结果:其作用是在线性表L的第i个位置上插入一个值为x的新元素。
(6)删除操作DelElem(L,i,x)
初始条件:线性表L存在且删除位置正确(1<=i<=n,n为删除前表的长度)
操作结果:其作用是删除线性表L的第i个位置的数据元素并用x将其存储。
(7)显示操作DispList(L)
初始条件:线性表L存在,且非空。
操作结果:其作用使依次扫描线性表L,并输出各元素的值。
(8)DestroyList(L):销毁线性表。
二、线性表的顺序存储
1、顺序表的定义
数据结构在内存中的表示通常有两种形式,即顺序存储表示和链式存储表示。线性表的顺序存储是指用一组地址连续的存储单位依次存储线性表的数据元素,我们把用这种存储形式存储的线性表称为顺序表。线性表的顺序存储表示又称为顺序表。顺序表的逻辑顺序和物理顺序是一致的。
2、顺序表的存储特点
(1)顺序表的逻辑顺序和物理顺序是一致的。
(2)顺序表中任意一个数据元素都可以随机存取,所以顺序表是一种随机存取的存储结构。
3、顺序表的类型定义
typedef int datafype;//创建线性表
typedef struct {
datafype data[MAX];
int Length;
}SeqList;
SeqList l;
顺序表SeqList是一个结构体类型,它由两个成员组成:data表示存储顺序表的数组,其长度MAXLEN表示顺序表中元素数目的最大值;Length表示顺序表的实际长度。
4、顺序表的基本运算的实现。
(1)顺序表的初始化
int InitList(SeqList *l){//初始化线性表
if(!l->data)exit(NO);
l->Length=0;
return OK;
}
(2)顺序表的建立
void CreateList(SeqList *l,int n){//给线性表中赋值
int i;
for(i=0;i<n;i++){
scanf("%d",&l->data[i]);
}
l->Length=i;
}
(3)查找操作(按位置查找)
int GetElem(SeqList *l,int i,datafype *e){// 线性表按位置查找
if(i<1||i>l->Length)
return NO;
*e=l->data[i-1];
return OK;
}
(4)查找操作(按值查找)
int LocateElem(SeqList *l,datafype e){//线性表按值查找
int i;
for(i=0;i<l->Length;i++){
if(l->data[i]==e) return i+1;
}
return NO;
}
/*int LocateElem(SeqList *l,datafype e){//按值查找
int i=0;
while(i<l->Length&&l->data[i]!=e){
i++;
if(i>=l->Length){
return NO;
}else{
return i+1;
}
}
}*/
(5)插入查找
int InsElem(SeqList *l ,int i,datafype e){//线性表插入操作
int j;
for(j=l->Length-1;j=i-1;j--){
if(l->Length>=MAX){
printf("线性表已满!!");
return NO;
}
if(i<1||i>l->Length+1){
printf("插入错误!!!");
return NO;
}
if(i==l->Length+1){
l->data[i-1]=e;
l->Length++;
return OK;
}
l->data[j+1]=l->data[j];
l->data[i-1]=e;
l->Length++;
return OK;
}
}
(6)删除操作
int DelElem(SeqList *l,int i,datafype *e){//线性表删除操作
int j;
for(j=i;j<l->Length;j++){
if(l->Length==0){
printf("表为空!!");
return NO;
}
if(i<1||i>l->Length){
printf("不存在元素i!!");
return NO;
}
*e=l->data[i-1];
l->data[i-1]=l->data[j];
l->Length--;
return OK;
}
}
(6)输出表中元素操作
void DispList(SeqList *l){
int i;
for(i=0;i<l->Length;i++){
printf("%3d",l->data[i]);
}
}
(7)显示菜单函数
void Menu(){
printf("\n 顺序表操作顺序");
printf("\n================================");
printf("\n| 1--建立顺序表 ");
printf("\n| 2--判断顺序表是否为空");
printf("\n| 3--查看顺序表长度 ");
printf("\n| 4--插入元素 ");
printf("\n| 5--删除元素 ");
printf("\n| 6--按位置查找元素 ");
printf("\n| 7--按数值查找元素 ");
printf("\n| 8--重置顺序表 ");
printf("\n| 9--销毁顺序表 ");
printf("\n| 0--返回 ");
printf("\n================================");
printf("\n请输入菜单号0~9:");
}
三、配套实验
实验:顺序表表子系统
(1)掌握线性表的特点及其存储的方式。
(2)掌握线性表顺序存储的基本运算。
(3)掌握线性表的创建、插入、删除和显示线性表中元素等的基本操作。
#define MAX 100
#define OK 1
#define NO -1
#include<stdio.h>
#include<stdlib.h>
typedef int datafype;//创建线性表
typedef struct {
datafype data[MAX];
int Length;
}SeqList;
SeqList l;
int InitList(SeqList *l){//初始化线性表
if(!l->data)exit(NO);
l->Length=0;
return OK;
}
void CreateList(SeqList *l,int n){//给线性表中赋值
int i;
for(i=0;i<n;i++){
scanf("%d",&l->data[i]);
}
l->Length=i;
}
int DestoryList(SeqList *l){//销毁线性表
if(l->data)delete l->data;
return OK;
}
int ClearList(SeqList *l){//重置线性表
l->Length=0;
return OK;
}
int GetLength(SeqList *l){//返回线性表的长度
return(l->Length);
}
int IsEmpty(SeqList *l){//判断线性表是否为空
if(l->Length==0) return OK;
else return NO;
}
int GetElem(SeqList *l,int i,datafype *e){// 线性表按位置查找
if(i<1||i>l->Length)
return NO;
*e=l->data[i-1];
return OK;
}
int LocateElem(SeqList *l,datafype e){//线性表按值查找
int i;
for(i=0;i<l->Length;i++){
if(l->data[i]==e) return i+1;
}
return NO;
}
/*int LocateElem(SeqList *l,datafype e){//按值查找
int i=0;
while(i<l->Length&&l->data[i]!=e){
i++;
if(i>=l->Length){
return NO;
}else{
return i+1;
}
}
}*/
int InsElem(SeqList *l ,int i,datafype e){//线性表插入操作
int j;
for(j=l->Length-1;j=i-1;j--){
if(l->Length>=MAX){
printf("线性表已满!!");
return NO;
}
if(i<1||i>l->Length+1){
printf("插入错误!!!");
return NO;
}
if(i==l->Length+1){
l->data[i-1]=e;
l->Length++;
return OK;
}
l->data[j+1]=l->data[j];
l->data[i-1]=e;
l->Length++;
return OK;
}
}
int DelElem(SeqList *l,int i,datafype *e){//线性表删除操作
int j;
for(j=i;j<l->Length;j++){
if(l->Length==0){
printf("表为空!!");
return NO;
}
if(i<1||i>l->Length){
printf("不存在元素i!!");
return NO;
}
*e=l->data[i-1];
l->data[i-1]=l->data[j];
l->Length--;
return OK;
}
}
void DispList(SeqList *l){
int i;
for(i=0;i<l->Length;i++){
printf("%3d",l->data[i]);
}
}
void Menu(){
printf("\n 顺序表操作顺序");
printf("\n================================");
printf("\n| 1--建立顺序表 ");
printf("\n| 2--判断顺序表是否为空");
printf("\n| 3--查看顺序表长度 ");
printf("\n| 4--插入元素 ");
printf("\n| 5--删除元素 ");
printf("\n| 6--按位置查找元素 ");
printf("\n| 7--按数值查找元素 ");
printf("\n| 8--重置顺序表 ");
printf("\n| 9--销毁顺序表 ");
printf("\n| 0--返回 ");
printf("\n================================");
printf("\n请输入菜单号0~9:");
}
int main(){
SeqList l;
datafype e;
int n,i,loc;
char ch1,ch2,a;
ch1='y';
while(ch1=='y'||ch1=='Y'){
Menu();
scanf("%c",&ch2);
getchar();
switch(ch2){
case '1':
InitList(&l);
printf("要建立多少个元素的线性表:");
scanf("%d",&n);
printf("输入元素的个数:");
CreateList(&l,n);
printf("建立的线性表为:");
DispList(&l);
break;
case '2':
if(IsEmpty(&l)>0){
printf("这线性表为空表!");
}else{
printf("线性表不为空,它的元素如下:\n");
DispList(&l);
}
break;
case '3':
printf("这线性表长度为:%d",GetLength(&l));
break;
case '4':
printf("输入要插入的位置:");
scanf("%d",&i);
printf("请输入要插入的元素值:");
scanf("%d",&e);
if(InsElem(&l,i,e)>0){
printf("已成功在第%d的位置上插入%d,插入后的线性表元素排序如下:\n",i,e);
DispList(&l);
} else{
printf("插入失败!!!");
}
break;
case '5':
printf("输入要删除的位置:");
scanf("%d",&i);
if(DelElem(&l,i,&e)>0){
printf("已成功在%d的位置上删除%d,删除后的线性表元素排序如下:\n",i,e);
DispList(&l);
} else{
printf("删除失败!!!");
}
break;
case '6':
printf("输入要查找的元素位置(从1开始):");
scanf("%d",&i);
if(GetElem(&l,i,&e)>0){
printf("在当前线性表第%d个元素的值为:%d",i,e);
} else{
printf("输入的位置错误!!!");
}
break;
case '7':
printf("输入要查找的元素值:");
scanf("%d",&i);
loc=LocateElem(&l,e);
if(loc) {
printf("在当前线性表第%d个元素的位置为:%d",i,loc);
}else{
printf("表中无此元素!!");
}
break;
case '8':
if(ClearList(&l)>0){
printf("重置成功");
printf("重置后的表元素:\n");
DispList(&l);
}else{
printf("重置失败!");
}
break;
case '9':
if(DestoryList(&l)>0){
printf("线性表以成功销毁");
}else{
printf("线性表销毁失败!");
}
break;
case '0':
ch1='n';
break;
default:
printf("输入错误!!请输入0~9进行选择!");
}
if(ch2!='0'){
printf("\n按回车键继续,按任意键返回主菜单!\n");
a=getchar();
if(a!='\xA'){
getchar();
ch1='n';
}
}
}
}