顺序表
顺序表从字面意思就能理解它的一个顺序存储的一种线性表,按物理地址连续的存储单元来存储数据元素,一般情况下是用数组来存储,因为数组中的元素是随机存取的,并且根据具体要求所需的增添和删除等的操作都是在数组里进行的。一般顺序表分为两种:
1.静态顺序表:使用定长数组存储。
2.动态顺序表:使用动态开辟的内存存储。

根据需要的动态分配大小,实现接口,代码如下:
顺序表代码
#ifndef _COMMON_H_
#define _COMMON_H_
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef enum{FALSE, TRUE} BOOL;
#define DataType int
#define DEFAULT_SIZE 8
#define INC_SIZE 3
#endif /* _COMMON_H_ */
#ifndef _SEQLIST_H_
#define _SEQLIST_H_
#define NULL_DATA -1
typedef struct SeqList
{
DataType *base;
size_t capacity;
size_t size;
}SeqList;
//内部方法
static BOOL _Inc(SeqList *psl);
BOOL SeqListIsFull(SeqList *psl);//是否满
BOOL SeqListIsEmpty(SeqList *psl);//是否空
void SeqListInit(SeqList* psl, size_t capacity);//初始化
void SeqListPushBack(SeqList* psl, DataType x);//尾插
void SeqListPushFront(SeqList* psl, DataType x);//头插
void SeqListShow(SeqList *psl);//展示表
void SeqListPopBack(SeqList* psl);//尾删
void SeqListPopFront(SeqList* psl);//头删
size_t SeqListLength(SeqList *psl);//长度
void SeqListClear(SeqList *psl);//清除
DataType SeqListFindByPos(SeqList *psl, int pos);//通过位置查找
int SeqListFindByVal(SeqList *psl, DataType key);//通过值查找
BOOL SeqListEraseByVal(SeqList *psl, DataType key);//通过值删除
BOOL SeqListEraseByPos(SeqList *psl, int pos);//按位置删除
BOOL SeqListInsertByPos(SeqList *psl, int pos, DataType x);//按位置插入
void SeqListReverse(SeqList *psl);//逆序
void SeqListRemoveAll(SeqList* psl, DataType x);//移除所有
void SeqListSort(SeqList *psl);//排序
void SeqListDestroy(SeqList *psl)//;摧毁表
BOOL _Inc(SeqList *psl)
{
DataType *new_base =
(DataType *)malloc(sizeof(DataType)*(psl->capacity + INC_SIZE));
if (new_base == NULL)
return FALSE;
memcpy(new_base, psl->base, sizeof(DataType)*psl->capacity);
free(psl->base);
psl->base = new_base;
psl->capacity += INC_SIZE;
return TRUE;
}
BOOL SeqListIsFull(SeqList *psl)
{
if (psl->size >= psl->capacity)
return TRUE;
return FALSE;
}
BOOL SeqListIsEmpty(SeqList *psl)
{
if (psl->size == 0)
return TRUE;
return FALSE;
}
////////////////////////////////////////////////////////////
void SeqListInit(SeqList* psl, size_t capacity)
{
psl->base = (DataType*)malloc(sizeof(DataType)*capacity);
assert(psl->base != NULL);
psl->capacity = capacity;
psl->size = 0;
}
void SeqListPushBack(SeqList* psl, DataType x)
{
if (SeqListIsFull(psl) && !_Inc(psl))
{
printf("顺序表空间已满,%d不能插入.\n", x);
return;
}
psl->base[psl->size++] = x;
}
void SeqListPushFront(SeqList* psl, DataType x)
{
if (SeqListIsFull(psl) && !_Inc(psl))
{
printf("顺序表空间已满,%d不能插入.\n", x);
return;
}
for (int i = psl->size; i > 0; --i)
{
psl->base[i] = psl->base[i - 1];
}
psl->base[0] = x;
psl->size++;
}
void SeqListShow(SeqList *psl)
{
for (int i = 0; i < psl->size; ++i)
{
printf("%d ", psl->base[i]);
}
printf("\n");
}
void SeqListPopBack(SeqList* psl)
{
if (SeqListIsEmpty(psl))
{
printf("顺序表已空,不能删除.\n");
return;
}
psl->size--;
}
void SeqListPopFront(SeqList* psl)
{
if (SeqListIsEmpty(psl))
{
printf("顺序表已空,不能删除.\n");
return;
}
for (int i = 0; i<psl->size-1; ++i)
{
psl->base[i] = psl->base[i + 1];
}
psl->size--;
}
size_t SeqListLength(SeqList *psl)
{
return psl->size;
}
void SeqListClear(SeqList *psl)
{
psl->size = 0;
}
DataType SeqListFindByPos(SeqList *psl, int pos)
{
//assert(pos >= 0 && pos < psl->size);
if (pos < 0 || pos >= psl->size)
{
printf("查询的位置无效.\n");
return NULL_DATA;
}
return psl->base[pos];
}
int SeqListFindByVal(SeqList *psl, DataType key)
{
for (int i = 0; i < psl->size; ++i)
{
if (key == psl->base[i])
return i;
}
return -1;
}
BOOL SeqListEraseByPos(SeqList *psl, int pos)
{
if (pos < 0 || pos >= psl->size)
return FALSE;
for (int i = pos; i < psl->size - 1; ++i)
psl->base[i] = psl->base[i + 1];
psl->size--;
return TRUE;
}
BOOL SeqListEraseByVal(SeqList *psl, DataType key)
{
int index = SeqListFindByVal(psl, key);
if (index == -1)
return FALSE;
return SeqListEraseByPos(psl, index);
}
BOOL SeqListInsertByPos(SeqList *psl, int pos, DataType x)
{
if (pos<0 || pos>psl->size)
return FALSE;
if (SeqListIsFull(psl) && !_Inc(psl))
{
printf("顺序表空间已满,%d不能插入.\n", x);
return FALSE;
}
for (int i = psl->size; i > pos; --i)
psl->base[i] = psl->base[i - 1];
psl->base[pos] = x;
psl->size++;
return TRUE;
}
void SeqListReverse(SeqList *psl)
{
if (psl->size >= 2)
{
int begin = 0;
int end = psl->size - 1;
while (begin < end)
{
Swap(&(psl->base[begin]), &(psl->base[end]));
begin++;
end--;
}
}
}
void SeqListRemoveAll(SeqList* psl, DataType x)
{
for (int i = 0; i < psl->size; ++i)
{
if (x == psl->base[i])
{
for (int j = i; j < psl->size-1; ++j)
psl->base[j] = psl->base[j + 1];
psl->size--;
i--;
}
}
}
void SeqListSort(SeqList *psl)
{
for (int i = 0; i < psl->size - 1; ++i)
{
for (int j = 0; j < psl->size - i - 1; ++j)
{
if (psl->base[j] > psl->base[j + 1])
{
Swap(&(psl->base[j]), &(psl->base[j + 1]));
}
}
}
}
void SeqListDestroy(SeqList *psl)
{
free(psl->base);
psl->base = NULL;
psl->capacity = psl->size = 0;
}
/*
BOOL SeqListEraseByVal(SeqList *psl, DataType key)
{
int index = SeqListFindByVal(psl, key);
if (index == -1)
return FALSE;
for (int i = index; i < psl->size - 1; ++i)
psl->base[i] = psl->base[i + 1];
psl->size--;
return TRUE;
}
*/
#endif /* _SEQLIST_H_ */
#include"common.h"
#include"seqlist.h"
int main(int argc, char *argv[])
{
seqlist mylist;
seqlistinit(&mylist, default_size);
datatype item;
int pos, index;
bool flag;
int select = 1;
while (select)
{
printf("************************************\n");
printf("* [1] push_back [2] push_front *\n");
printf("* [3] show_list [0] quit_system*\n");
printf("* [4] pop_back [5] pop_front *\n");
printf("* [6] find_pos [7] find_val *\n");
printf("* [8] insert_pos [9] delete_val *\n");
printf("* [10] delete_pos [11]length *\n");
printf("* [12] remove_all [13] reverse *\n");
printf("* [14] sort [15] clear *\n");
printf("************************************\n");
printf("请选择:>");
scanf("%d", &select);
if (select == 0)
break;
switch (select)
{
case 1:
printf("请输入要插入的数据(以-1结束):>");
while (scanf("%d", &item), item != -1)
{
seqlistpushback(&mylist, item);
}
break;
case 2:
printf("请输入要插入的数据(以-1结束):>");
while (scanf("%d", &item), item != -1)
{
seqlistpushfront(&mylist, item);
}
break;
case 3:
seqlistshow(&mylist);
break;
case 4:
seqlistpopback(&mylist);
break;
case 5:
seqlistpopfront(&mylist);
break;
case 6:
printf("请输入要查询的位置:>");
scanf("%d", &pos);
printf("要查询的数据:%d\n", seqlistfindbypos(&mylist, pos));
break;
case 7:
printf("请输入要查询的数据:>");
scanf("%d", &item);
index = seqlistfindbyval(&mylist, item);
if (index == -1)
printf("要查询的数据%d不存在.\n", item);
else
printf("要查询数据的下标为:>%d\n", index);
break;
case 8:
printf("请输入要插入的位置:>");
scanf("%d", &pos);
printf("请输入要插入的数据:>");
scanf("%d", &item);
flag = seqlistinsertbypos(&mylist, pos, item);
if (flag)
printf("插入成功.\n");
else
printf("插入失败.\n");
break;
case 9:
printf("请输入要删除的数据:>");
scanf("%d", &item);
flag = seqlisterasebyval(&mylist, item);
if (flag)
printf("删除%d成功.\n", item);
else
printf("删除%d失败.\n", item);
break;
case 10:
printf("请输入要删除的位置:>");
scanf("%d", &pos);
flag = seqlisterasebypos(&mylist, pos);
if (flag)
printf("删除成功.\n");
else
printf("删除失败.\n");
break;
case 11:
printf("seqlist length = %d\n", seqlistlength(&mylist));
break;
case 12:
printf("请输入要删除的数据:>");
scanf("%d", &item);
seqlistremoveall(&mylist, item);
break;
case 13:
seqlistreverse(&mylist);
break;
case 14:
seqlistsort(&mylist);
break;
case 15:
seqlistclear(&mylist);
break;
}
}
seqlistdestroy(&mylist);
return 0;
}
线性表的不足和问题也很明显:
1.时间复杂度为o(n)
2.有不小的消耗
3.内存的浪费

顺序表是一种线性表,采用物理地址连续的数组存储数据元素。包括静态顺序表(定长数组)和动态顺序表(动态内存开辟)。虽然便于随机存取,但增删操作时间复杂度高,可能导致内存浪费。
4375

被折叠的 条评论
为什么被折叠?



