数据结构(超详细讲解!!)第一节 线性表

1.线性表的定义

线性表(Linear List)是由n (n≥0)个类型相同的数据元素a1,a2,…,an组成的有限序列,记做 L=(a1,a2,…,ai-1,ai,ai+1, …,an)。 ai 是数据元素,L是表名,可以用标识符来命名。 其中n为表长,n=0 时称为空表。 数据元素之间是一对一的关系,即每个数据元素最多有一个直接前驱和一个直接后继。 线性表的逻辑结构图为:

在数据元素的非空有限集中,存在唯一的一个被称作第一个的数据元素;存在唯一的一个被称作最后一个的数据元素; 除第一个之外,集合中的每个数据元素均只有一个前驱;除最后一个之外,集合中的每个数据元素均只有一个后继。

需要说明的是:ai为序号为i的数据元素,它只是个抽象符号,其具体含义在不同情况下可以不同。 通常我们将它的数据类型抽象为ElemSet, ElemSet根据具体问题而定。

2.线性表的特点

同一性:线性表由同类数据元素组成,每一个ai必须属于同一数据对象(数据类型是一致)。

有穷性:线性表由有限个数据元素组成,表长度就是表中数据元素的个数。

有序性:线性表中相邻数据元素之间存在着序偶关系。所有元素具有次序之分,除了a1无前趋,an无后继,其余元素均有自己的直接前驱和直接后继。

3.用C语言定义顺序表

(1).定义顺序表

#define	maxsize=线性表可能达到的最大长度;
typedef  struct  
{ 
     ElemType  elem[maxsize];  /* 线性表占用的数组空间*/
     int  last; /*记录线性表中最后一个元素在数组elem[ ]中的位置(下标值),空表置为-1*/
   } SeqList;
#include
#include

#define maxsize 100

typedef char ElemType;//数据类型由此更改
//定义顺序表 
typedef struct
{ElemType elem[maxsize];
int last;
}SeqList;

(2).顺序表的不同声明

两种不同的声明方式:
1.变量定义
  声明一个顺序表:SeqList L;

  第一个结点:a1=L.elem[0] ;

  终端结点:an=L.elem[L.last];

  表长:len=L.elem+1

2.指针变量定义
声明一个顺序表:SeqList  *L;/*L是一个指针变量*/
 
线性表的存储空间通过
  L=(SeqList *)malloc(sizeof(SeqList))操作来获得。

表长表示为:  
 (*L).last+1  或  L->last+1 

L的第一个结点:
  a1=(*L).elem[0]   或  L->data[0]
终端结点:
 an=(*L).elem[(*L).last]  或 L->elemL->last]

4.顺序表的基本操作

(1).初始化顺序表(建立一个空的顺序表)

//创建顺序表
SeqList * Init_SeqList()
{SeqList *L;
L=(SeqList *) malloc (sizeof(SeqList));
if(L!=NULL)
{L->last=-1;
}
printf("成功创建一个顺序表\n"); 
return L;
}

(2).顺序表录入数据

//顺序表录入数据
SeqList * indata_SeqList(SeqList *L)
{ElemType x;
printf("请为顺序表录入数据\n");
scanf(" %c",&x);
while(x!='#')//若为int,则结尾可用0做标识符
{L->last+=1;
L->elem[L->last]=x;
scanf("%c",&x);
}
printf("数据录入成功\n");
return L;
}

(3).输出顺序表

//输出顺序表
void printf_SeqList(SeqList *L)
{int i=0;
printf("输出顺序表数据:\n");
for(i=0;ilast+1;i++)
{printf("%c",L->elem[i]);
}
printf("\n");
}

(4).表长

//表长 
int SeqList_Length(SeqList *L)
{printf("顺序表表长为:%d\n",L->last+1);
return(L->last+1);
 } 

(5).按序号查找

//按序号查找 
 int GetData_SeqList(SeqList *L)
 {int i;
 printf("\n请输入需要查找的序号:") ;
scanf(" %d",&i);
 if(i<1||i>L->last+1)
 {printf("序号不存在"); 
 return 0;
 }
 else
 {
printf("%c",L->elem[i-1]); 
 return (L->last+1);}
 }

(6).按内容查找

 //按内容查找 
 int Locate(SeqList *L)
 {int i,j=0; 
 ElemType key;
 printf("\n请输入需要查找的内容:") ;
 scanf(" %c",&key);
 for(i=0;i<=L->last;i++)
 if(L->elem[i]==key)
 {printf("所查找的内容为第%d个元素",i+1);
 return(i+1);
 }
 printf("该内容不存在");
 return 0;
 }

(7).插入

//插入 
int Insert_SeqList(SeqList *L)
{int i,j;
ElemType e;
printf("\n请输入插入的位置和内容:");
scanf("%d %c",&i,&e);
if(L->last>=maxsize-1)
{printf("表已满无法插入\n");
return 0;
}
if((i<1)||(i>L->last+2))
{printf("插入位置i不合法");
return -1;
}
for(j=L->last;j>=i-1;j--)
L->elem[j+1]=L->elem[j];
L->elem[i-1]=e;
L->last++;
return 1;
}

(8).删除

//删除
int Delete_SeqList(SeqList *L)
{	int i,k;
	ElemType n;
	ElemType *e;
	e=&n;
	printf("\n请输入删除的位置:");
	scanf("%d",&i);
	if((i<1)||(i>L->last+1))
	{
		printf("删除位置不合法!");
		return 0; 
	}
	else
	{*e=L->elem[i-1];
	for(k=i;k<=L->last;k++)
	L->elem[k-1]=L->elem[k];
	L->last--;
	}
	return 1;
 } 

(9).遍历

//遍历
void Print_SequenList(SeqList *L)
{int i;
printf("顺序表内存地址:\n"); 
for(i=0;i<=L->last;i++)
{printf("a[%2d]=%4c\t",i+1,L->elem[i]);
if((i+1)%5==0)
printf("\n");
}
 } 

5.例题:

编写实现顺序表的基本算法(初始化、查找、插入、删除等)的函数,并在此基础上设计一个主程序完成如下功能:

⑴初始化一个顺序表L;

⑵建立顺序表L,要求数据元素至少10个;

⑶输出顺序表L的长度;

⑷按位置查找:输出顺序表L的第i个元素,如第3个元素;

⑸按内容查找:输出给定元素的位置;

⑹在第i个元素前插入给定元素;

⑺删除顺序表L的第i个元素;

遍历顺序表,将表中的元素按序输出。

编写菜单,以便用户可以选择相应的操作。

6.答案解析

(1).函数调用关系

void menu()菜单

typedef struct定义顺序表

SeqList * Init_SeqList()创建顺序表

SeqList * indata_SeqList(SeqList *L)顺序表录入数据

void printf_SeqList(SeqList *L)输出顺序表

int SeqList_Length(SeqList *L)表长

int GetData_SeqList(SeqList *L)按序号查找

int Locate(SeqList *L)按内容查找

int Insert_SeqList(SeqList *L)插入

int Delete_SeqList(SeqList *L)删除

void Print_SequenList(SeqList *L)遍历

(2)操作过程

菜单

数据结构(超详细讲解!!)第一节 线性表_第1张图片

创建顺序表

录入顺序表

数据结构(超详细讲解!!)第一节 线性表_第2张图片

输出表长

按序号查找

        输入正确:

数据结构(超详细讲解!!)第一节 线性表_第3张图片

        输入错误:

数据结构(超详细讲解!!)第一节 线性表_第4张图片

按内容查找

         输入正确:

数据结构(超详细讲解!!)第一节 线性表_第5张图片

         输入错误:

插入

        输入正确:

数据结构(超详细讲解!!)第一节 线性表_第6张图片

数据结构(超详细讲解!!)第一节 线性表_第7张图片

        输入错误:

删除

        输入正确:

数据结构(超详细讲解!!)第一节 线性表_第8张图片

数据结构(超详细讲解!!)第一节 线性表_第9张图片

        输入错误:

遍历

输出顺序表

数据结构(超详细讲解!!)第一节 线性表_第10张图片

结束程序

数据结构(超详细讲解!!)第一节 线性表_第11张图片

(3).代码

#include
#include
#include
#include

#define maxsize 100

typedef char ElemType;
//定义顺序表 
typedef struct
{ElemType elem[maxsize];
int last;
}SeqList;
//创建顺序表
SeqList * Init_SeqList()
{SeqList *L;
L=(SeqList *) malloc (sizeof(SeqList));
if(L!=NULL)
{L->last=-1;
}
printf("成功创建一个顺序表\n"); 
return L;
}
//顺序表录入数据
SeqList * indata_SeqList(SeqList *L)
{ElemType x;
printf("请为顺序表录入数据\n");
scanf(" %c",&x);
while(x!='#')
{L->last+=1;
L->elem[L->last]=x;
scanf("%c",&x);
}
printf("数据录入成功\n");
return L;
}
//输出顺序表
void printf_SeqList(SeqList *L)
{int i=0;
printf("输出顺序表数据:\n");
for(i=0;ilast+1;i++)
{printf("%c",L->elem[i]);
}
printf("\n");
}
//表长 
int SeqList_Length(SeqList *L)
{printf("顺序表表长为:%d\n",L->last+1);
return(L->last+1);
 } 
 //按序号查找 
 int GetData_SeqList(SeqList *L)
 {int i;
 printf("\n请输入需要查找的序号:") ;
scanf(" %d",&i);
 if(i<1||i>L->last+1)
 {printf("序号不存在"); 
 return 0;
 }
 else
 {
printf("%c",L->elem[i-1]); 
 return (L->last+1);}
 }
 //按内容查找 
 int Locate(SeqList *L)
 {int i,j=0; 
 ElemType key;
 printf("\n请输入需要查找的内容:") ;
 scanf(" %c",&key);
 for(i=0;i<=L->last;i++)
 if(L->elem[i]==key)
 {printf("所查找的内容为第%d个元素",i+1);
 return(i+1);
 }
 printf("该内容不存在");
 return 0;
 }
//插入 
int Insert_SeqList(SeqList *L)
{int i,j;
ElemType e;
printf("\n请输入插入的位置和内容:");
scanf("%d %c",&i,&e);
if(L->last>=maxsize-1)
{printf("表已满无法插入\n");
return 0;
}
if((i<1)||(i>L->last+2))
{printf("插入位置i不合法");
return -1;
}
for(j=L->last;j>=i-1;j--)
L->elem[j+1]=L->elem[j];
L->elem[i-1]=e;
L->last++;
return 1;
}
//删除
int Delete_SeqList(SeqList *L)
{	int i,k;
	ElemType n;
	ElemType *e;
	e=&n;
	printf("\n请输入删除的位置:");
	scanf("%d",&i);
	if((i<1)||(i>L->last+1))
	{
		printf("删除位置不合法!");
		return 0; 
	}
	else
	{*e=L->elem[i-1];
	for(k=i;k<=L->last;k++)
	L->elem[k-1]=L->elem[k];
	L->last--;
	}
	return 1;
 } 
//遍历
void Print_SequenList(SeqList *L)
{int i;
printf("顺序表内存地址:\n"); 
for(i=0;i<=L->last;i++)
{printf("a[%2d]=%4c\t",i+1,L->elem[i]);
if((i+1)%5==0)
printf("\n");
}
 } 
 
//菜单
void menu()
{//system("cls");
printf("--------1.初始化顺序表------------\n"); 
printf("--------2.建立顺序表--------------\n"); 
printf("--------3.输出顺序表的长度--------\n"); 
printf("--------4.按序号查找顺序表--------\n"); 
printf("--------5.按内容查找顺序表--------\n"); 
printf("--------6.插入元素----------------\n"); 
printf("--------7.删除元素----------------\n"); 
printf("--------8.遍历顺序表--------------\n"); 
printf("--------9.输出顺序表------------ -\n");
printf("--------10.退出程序---------------\n"); 
printf("-------------请输入需要执行的内容:\n");  
 } 

//主函数 
int main()
{SeqList *L,*LA,*LB;
int a,quit=0; 
menu();
while(1)
{
scanf("%d",&a);
switch(a)
{case 1:L=Init_SeqList();break;
case 2:L=indata_SeqList(L);break;
case 3:SeqList_Length(L);break;
case 4:GetData_SeqList(L);break;
case 5:Locate(L);break;
case 6:Insert_SeqList(L);break;
case 7:Delete_SeqList(L);break;
case 8:Print_SequenList(L);break;
case 9:printf_SeqList(L);break;
case 10:quit=1;break;
default:printf("输入1~10之间的数字\n");break;
}
if(quit==1)
{break;
}

}
return 0;
}

7.练习题

 利用顺序表的基本操作,求两个集合A和B的交集、并集和差集。

(答案在下一篇文章)

你可能感兴趣的:(数据结构(超详细讲解!!),数据结构)