【数据结构之顺序表的的表示和实现】

181 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情

一、什么是顺序表?

顺序表是线性表的一种,是指用一组地址连续的存储单元依次存储线性表的数据元素。其特点是,逻辑上相邻的数据元素,其物次序也是相邻的。所以顺序表具有随机存取的性质。

二、顺序表中基本操作的实现

        顺序表中的基本操作有很多取值、赋值、查找、插入、删除、排序、销毁、重置等等。

1.预处理及定义顺序表类型:

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100 //设置顺序表的最大长度为100
#define TRUE 1 
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;  
typedef char ElemType; 
//定义顺序表类型
typedef struct
{
	ElemType* elem;//此处为静态数组也可使用静态数组ElemType elem[MAXSIZE]代替
	int length;    //用于表示顺序表的长度
}SqList;

2.顺序表的初始化

//线性表的初始化 
Status InitList(SqList &L)            
{
    //构造一个顺序表L
	L.elem = new ElemType[MAXSIZE];   //为顺序表分配一个大小为MAXSIZE的数组空间
	if (!L.elem) exit(OVERFLOW);     //异常处理提高代码的健壮性
	L.length = 0;                   //空表长度为0
	return OK;
}

3.顺序表的赋值

void CreateSqList(SqList* L, int n)   //n为需要创建顺序表的长度
{
	int i = 0;
    //异常处理:
	if (n > MAXSIZE || n < 1)        
	{
		printf("顺序表的长度非法");
	}
	else
	{
		printf("请输入%d个数据:", n);
		for (i = 0; i < n; i++)
		{
			scanf_s("%d", &L->elem[i]);
			L->length++;
		}
	}
}

4.顺序表的打印

void PrintList(SqList L)   
{
	int i = 0;
	for (i = 0; i < L.length; i++) {
		printf("%d ", L.elem[i]);
	}printf("\n");
}

5.顺序表的插入

注意:一个长度为N的顺序表有N+1个位置可以插入
Status ListInsert(SqList& L, int i, ElemType e)//i表示要插入的位置
{                                             //e表示要插入的数据元素
	int j = 0;
	if ((i < 1) || (i > L.length + 1)) return ERROR;//异常处理
	if (L.length == MAXSIZE) return ERROR;
        printf("在第%d个位置插入:\n", i);        //提示语
	for (j = L.length - 1; j >= i - 1; j--)
		L.elem[j + 1] = L.elem[j];         //数据元素依次都已覆盖
	L.elem[i - 1] = e;        //插入数据元素
	++L.length;               //长度加一
	return OK;
}

6.顺序表的删除

Status ListDelete(SqList& L, int i) //i表示要删除的位置
{
	int j = 0;
	if ((i < 1) || (i > L.length)) return ERROR;
    printf("删除第%d个数据元素:\n",i);   //提示语
	for (j = i; j <= L.length - 1; j++)
		L.elem[j - 1] = L.elem[j];     //数据元素依次前移覆盖
	--L.length;                        //长度减一
	return OK;
}

7.主函数

int main()
{
	SqList L;
	ElemType e=100;       //准备插入的数据元素
	int i;
	InitList(L);          //创建一个空表
	CreateSqList(&L, 3);  //创建指定大小的顺序表
	PrintList(L);         //打印顺序表
	ListInsert(L, 2, e);  //插入指定位置的数据元素
	PrintList(L);         //打印顺序表
	ListDelete(L, 1);     //删除指定位置的数据元素
	PrintList(L);         //打印顺序表
	return 0;
}

8.测试与运行结果

请输入3个数据:1 11 111
1 11 111
在第2个位置插入:
1 100 11 111
删除第1个数据元素:
100 11 111

总结:

        顺序表可以随机存取表中的任一元素,其存储位置可用一简单、直观的公式来表示。然而,从另一方面看,这个特点也造成了这种存储结构的缺点:再次插入或删除操作时,需要移动大量元素。另外由于数组有长度的相对固定的静态特性,当表中数据元素较多且变化较大时,操作过程相对复杂,必然导致存储空间的浪费。所以这些问题,都快可以通过线性表的另一种方式——链式存储结构来解决。

完整代码

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;//这是干嘛??
typedef char ElemType;
//定义顺序表类型
typedef struct
{
	ElemType* elem;//动态数组的方式
	//	ElemType elem[MAXSIZE];静态数组的方式
	int length;
}SqList;

//线性表的初始化 
Status InitList(SqList &L)
{
	L.elem = new ElemType[MAXSIZE];
	if (!L.elem) exit(OVERFLOW);//异常处理——健壮性
	L.length = 0;
	return OK;
}

Status GetElem(SqList L, int i, ElemType& e)
{
	if (i<1 || i>L.length) return ERROR;
	e = L.elem[i - 1];
	return OK;
}

int LocateElem(SqList L, ElemType e)
{
	int i = 0;
	for (i = 0; i < L.length; i++) 
		if (L.elem[i] == e) return i + 1;
	return 0;
}

Status ListInsert(SqList& L, int i, ElemType e)
{
	int j = 0;
	if ((i < 1) || (i > L.length + 1)) return ERROR;
	if (L.length == MAXSIZE) return ERROR;
	printf("在第%d个位置插入:\n", i);
	for (j = L.length - 1; j >= i - 1; j--)
		L.elem[j + 1] = L.elem[j];
	L.elem[i - 1] = e;
	++L.length;
	return OK;
}

Status ListDelete(SqList& L, int i)
{
	int j = 0;
	printf("删除第%d个数据元素:\n",i);
	if ((i < 1) || (i > L.length)) return ERROR;
	for (j = i; j <= L.length - 1; j++)
		L.elem[j - 1] = L.elem[j];
	--L.length;
	return OK;
}

void CreateSqList(SqList* L, int n)   //n为需要创建顺序表的长度
{
	int i = 0;
	if (n > MAXSIZE || n < 1)
	{
		printf("顺序表的长度非法");
	}
	else
	{
		printf("请输入%d个数据:", n);
		for (i = 0; i < n; i++)
		{
			scanf_s("%d", &L->elem[i]);
			L->length++;
		}
	}
}

void PrintList(SqList L)
{
	int i = 0;
	for (i = 0; i < L.length; i++) {
		printf("%d ", L.elem[i]);
	}printf("\n");
}

int main()
{
	SqList L;
	ElemType e=100;
	int i;
	InitList(L);//创建一个空表
	CreateSqList(&L, 3);//创建指定大小的顺序表
	PrintList(L);//打印顺序表
	ListInsert(L, 2, e);//插入指定位置的数据元素
	PrintList(L);//打印顺序表
	ListDelete(L, 1);//删除指定位置的数据元素
	PrintList(L);//打印顺序表
	return 0;
}