线性表
线性结构的特点:
- 存在唯一的一个被称做“第一个”的数据元素;
- 存在唯一的一个被称做“最后一个”的数据元素;
- 除第一个之外,集合中的每个数据元素均只有一个前驱;
- 除最后一个之外,集合中的每个数据元素均之后一个后继
线性表(linear_list)是最常用且最简单的一种数据结构。线性表是n个数据元素的有限序列。在稍微复杂的线性表中,一个数据元素可以由若干个数据项(item)组成。在这种情况下,常把数据元素称为记录(record),含有大量记录的线性表又称文件(file)
**线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素。**线性表的顺序存储结构或顺序映像(sequential mapping);
线性表的顺序实现:
SqList.h
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
typedef int Status; // Status是函数结果状态,成功返回TRUE,失败返回FALSE
#define LIST_INIT_SIZE 100 /*初始化长度*/
#define LISTINCREMNET 10 /*存储空间的分配增量*/
typedef int ElemType; /* "ElemType类型根据实际情况而定, 这里假设为int */
// 顺序表结构定义
typedef struct
{
ElemType *data; /* 存放顺序表元素的数组 */
int length; /* 线性表当前长度 */
int listsize; /*线性表分配的长度*/
}SqList;
SqList* initList(SqList* L); // 初始化操作
Status appendList(SqList* L, const ElemType e); // 附加元素操作
Status insertList(SqList* L, int i, const ElemType e); // 插入元素操作
Status deleteList(SqList*L, int i, ElemType& e); // 删除元素操作
Status getElem(SqList* L, int i, ElemType& e); // 获取元素操作
int locateElem(SqList*L, const ElemType e); // 查找元素位置操作
bool isEmpty(SqList* L); // 检测是否为空操作
int getLength(SqList* L); // 获取元素个数操作
void destroyList(SqList* L); // 销毁顺序表操作
void printList(SqList* L);
SqList.cpp
#include "SqList.h"
/*初始化线性表*/
SqList* initList(SqList*L)
{
L->data = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));
L->length = 0;
L->listsize = LIST_INIT_SIZE;
return L;
}
Status appendList(SqList* L, const ElemType e)
{
/*判断L是否初始化*/
if (!L->data) {
exit(-1);
}
/*判断是否溢出*/
if (L->length >= L->listsize) {
/*增加分配空间*/
ElemType* newBase = (ElemType*)realloc(L->data, (LIST_INIT_SIZE + LISTINCREMNET) * sizeof(ElemType));
if (!newBase) {
exit(-1);
}
L->data = newBase;
L->listsize += LISTINCREMNET;
}
/*插入元素*/
L->data[L->length] = e;
L->length++;
return TRUE;
}
Status insertList(SqList* L, int i, const ElemType e)
{
/*判断插入的位置是否合法*/
if (i<1 || i>L->length+1) {
exit(-1);
}
/*判断是否溢出*/
if (L->length >= L->listsize) {
/*增加分配空间*/
ElemType* newBase = (ElemType*)realloc(L->data, (LIST_INIT_SIZE + LISTINCREMNET) * sizeof(ElemType));
if (!newBase) {
exit(-1);
}
L->data = newBase;
L->listsize += LISTINCREMNET;
}
/*被插入的元素的右边元素右移*/
for (int j = L->length; j >= i; j--) {
L->data[j] = L->data[j - 1];
}
/*插入元素*/
L->data[i - 1] = e;
L->length++;
return TRUE;
}
Status deleteList(SqList* L, int i, ElemType& e)
{
/*判断删除的位置是否有效*/
if (i<1 || i>L->length) {
exit(-1);
}
e = L->data[i - 1];
for (int j = i - 1; j < L->length; j++) {
L->data[j] = L->data[j + 1];
}
L->length--;
return TRUE;
}
Status getElem(SqList* L, int i, ElemType& e)
{
/*判断i是否合法*/
if (i<1 || i>L->length) {
exit(-1);
}
e = L->data[i - 1];
return TRUE;
}
int locateElem(SqList* L, const ElemType e)
{
bool status = false;
for (int i = 0; i < L->length; i++) {
if (L->data[i] == e){
status = true;
return i;
}
}
if (!status) {
printf("线性表中没有该元素\n");
exit(-1);
}
}
bool isEmpty(SqList* L)
{
bool status = false;
if (!L->data) {
status = true;
printf("L为空表\n");
}
return status;
}
int getLength(SqList* L)
{
return L->length;
}
void destroyList(SqList* L)
{
free(L->data);
L->data = NULL;
L->length = 0;
L->listsize = 0;
}
void printList(SqList* L)
{
if (!L->data) {
exit(-1);
}
for (int i =0; i <L->length; i++) {
printf("\t%d", L->data[i]);
}
printf("\n");
}