(一)顺序表图文解析

         线性表的顺序指的是用一组地址连续的存储单位依次存储线性表的数据元素
                 特点:逻辑上相邻的数据元素,其物理次序也是相邻的。

假设线性表的每个元素占用L个存储单位(例如int整形占4个字节,则L=4;char字符型占一个字节,则L=1),并以所占的第一个单位的存储地址作为数据元素的存储起始位置;b为存储起始地址,由计算机随机分配,则线性表中第i+1个数据元素的存储位置为b+(i-1)×L

<mark>用简洁的话来讲</mark>

就是利用数组开辟一段连续的空间来存放数据元素,并给每个数据元素依次编号,方便利用数组下标序号来实现查找、插入、删除...等操作。

<mark>用通俗的话来讲</mark>

顺序表就像一个可以增加抽屉的屉子,从高到低依次给抽屉编号,你可以在抽屉里存放各种数据类型,顺序表的查找、插入、删除等操作就相当于依照抽屉的编号来查找抽屉里有什么东西,以及拿出或者放入东西。

(二) 顺序表代码解析

(1) 顺序表的基本操作

1.1 创建顺序表

//首先我们要定义一个结构体来存放数据
#define MaxSize 50 //定义MaxSize的大小为50
typedef char ElemType;		//定义ElemType的数据类型为char类型(即字符类型) 
typedef struct 				
{
	ElemType data[MaxSize];	//定义一个大小为50的数组
	int length;				//定义顺序表的长度
}SqList;					//定义SqList的数据类型为该结构体(包括char和int两个数据类型)

1.2 初始化顺序表

void InitList(SqList *&L)		//定义一个无参数返回的函数,L为SqList结构体类型
{
	L=(SqList *)malloc(sizeof(SqList)); //为L分配的空间,包括一段连续的数组空间和整型int的空间
	L->length=0;						//空表长度初始化为零
}

-----------------malloc函数分配空间的用法-------------
(分配类型 *)malloc(分配元素个数 *sizeof(分配类型))

1.3 置空顺序表

void ClearList(SqList *L)
{
	L->length=0;
}

1.4 销毁顺序表

void DestroyList(SqList *L)
{	
	free(L);   //对应于malloc函数,使用free释放空间
}

1.5 顺序表表长

int ListLength(SqList *L)
{
	return(L->length);	//直接返回length的值
}

1.6 判断顺序表是否为空

void ListEmpty(SqList *L)
{
	if(L->length==0)   
		printf("空!\n");
	else
		printf("非空!\n");
}

1.7 取顺序表第i个数据元素

void GetElem(SqList *L)
{ //可直接按序号查找
	int i;
	printf("请输入查找序号:");
	scanf("%d",&i);
	fflush(stdin);			//清除多余回车键,以便下次输入字符数据元素,详情请查看scanf()函数的输入问题
	if(i<1||i>L->length)    //若输入序号小于1或者大于表长则无法查找
		printf("错误!\n");
	else
		printf("查找数据为:%c\n",L->data[i-1]); //数组的第一个数据是从零开始计数的
}

1.8 查找顺序表某数据位置

void LocateElem(SqList *L)
{
	ElemType e;		//定义顺序表中的数据类型
	int i=0;		//i用作计数
	printf("请输入查找数据:");
	scanf("%c",&e);
	while(i<L->length&&L->data[i]!=e) //限制查找范围,即i不能大于表长
		i++;				//使用while循环体,遍历顺序表,直到查找到所输入的数据
	if(i>=L->length)		//若i大于表长则无法查找数据
		printf("查找失败!\n");
	else
		printf("查找序号为:%d\n",i+1); 		//若查找成功则返回该数据的物理序号
}

1.9 将某数据插入顺序表

void ListInsert(SqList *&L)
{
	int i,j;
	char e;
	printf("请输入插入的序号和数据:");
	scanf("%d %c",&i,&e);
	if(i<1||i>L->length+1)
		printf("输入序号错误!\n");
	i--;		//将物理序号转化为数组序号
	for(j=L->length;j>i;j--)		//尾插法
		L->data[j]=L->data[j-1]; 	//将所插入位置之后的数据向后移动一个单位
	L->data[i]=e;					//将所需插入的数据赋值给所腾出的位置
	L->length++;					//表长加一(length只作计数作用,记录顺序表的长短)
	printf("插入成功!\n");
}

1.10 删除顺序表中某数据

void ListDelete(SqList *&L,ElemType &e)
{	
	int i,j;
	printf("请输入需要删除的序号:");
	scanf("%d",&i);
	if(i<1||i>L->length+1)
		printf("输入序号错误!\n");
	i--;		//将物理序号转化为数组序号
	e=L->data[i];  		//将所删数据先交给e
	for(j=i;j<L->length-1;j++)
		L->data[j]=L->data[j+1];	//将所删数据后的数据向前移动一个单位
	L->length--;					//表长减一
	printf("删除成功!\n");
}

1.11 遍历顺序表

void TraverseList(SqList *L)
{
	int i;
	if(L->length==0)
		printf("顺序表为空!\n");
	for(i=0;i<L->length;i++)
		printf("%c ",L->data[i]);
	printf("\n");
}

(2) 顺序表源代码及测试

2.1 源代码

#include<stdio.h>
#include<malloc.h>
#define MaxSize 50
typedef char ElemType;
typedef struct 
{
	ElemType data[MaxSize];
	int length;
}SqList;

void InitList(SqList *&L)
{
	L=(SqList *)malloc(sizeof(SqList));
	L->length=0;
}
void ClearList(SqList *L)
{
	L->length=0;
}

void DestroyList(SqList *L)
{	
	free(L);
	L->length=0;
}

void ListEmpty(SqList *L)
{
	if(L->length==0)
		printf("空!\n");
	else
		printf("非空!\n");
}

int ListLength(SqList *L)
{
	return(L->length);
}

void TraverseList(SqList *L)
{
	int i;
	if(L->length==0)
		printf("顺序表为空!\n");
	for(i=0;i<L->length;i++)
		printf("%c ",L->data[i]);
	printf("\n");
}

void LocateElem(SqList *L)
{
	int i=0;
	ElemType e;
	printf("请输入查找数据:");
	scanf(" %c",&e);
	while(i<L->length&&L->data[i]!=e)
		i++;
	if(i>=L->length)
			printf("查找失败!\n");
		else
			printf("查找序号为:%d\n",i+1);
}

void GetElem(SqList *L)
{
	int i;
	printf("请输入查找序号:");
	scanf(" %d",&i);
	if(i<1||i>L->length)
		printf("错误!\n");
	else
		printf("查找数据为:%c\n",L->data[i-1]);
}

void ListInsert(SqList *&L)
{
	int i,j;
	ElemType e;
	printf("请输入插入的序号和数据:");
	scanf("%d %c",&i,&e);
	if(i<1||i>L->length+1)
		printf("输入序号错误!\n");
	i--;
	for(j=L->length;j>i;j--)
		L->data[j]=L->data[j-1];
	L->data[i]=e;
	L->length++;
	printf("插入成功!\n");
}


void ListDelete(SqList *&L,ElemType &e)
{	
	int i,j;
	printf("请输入需要删除的序号:");
	scanf("%d",&i);
	if(i<1||i>L->length+1)
		printf("输入序号错误!\n");
	i--;
	e=L->data[i];
	for(j=i;j<L->length-1;j++)
		L->data[j]=L->data[j+1];
	L->length--;
	printf("删除成功!\n");
}


int main()
{ 
	int k;
	ElemType e;
	SqList *L;
	InitList(L);
	while(1)
	{		
		ListInsert(L);
		printf("输入0停止插入,输入1继续插入\n");
		scanf("%d",&k);
		if(k==0)
			break;
	}
	ListDelete(L,e);
	TraverseList(L);
	printf("顺序表长度为:%d\n",ListLength(L));
	GetElem(L);
	LocateElem(L);	
	DestroyList(L);
	ClearList(L);
	ListEmpty(L);
	return 0;
}

2.2 测试结果

测试环境 : Windows 10
编译软件 : Visual C++ 6.0