顺序表
顺序表是一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储,在数组上完成数据 的增删查改。顺序表又分为静态顺序表和动态顺序表
1、使用静态顺序表存储
typedef int DataType
#define MAX_SIZE 100
struct SeqList{
DataType array[MAX_SIZE];//用来存储顺序表中的元素
int size;//顺序表中有效元素的个数
};
因为数组存储的元素是有限的,此处我们定义的是100。数组的空间是固定的,这个就是按静态顺序表存储 的。如果我们此时想存储101个元素,这个时候这个程序就得修改数组的大小了。所以一般情况下我们都采用动态顺序表来存储。
2、使用动态顺序表存储
typedef int DataType;
typedef struct{
DataType* _array;
int _capacity;//顺序表的总大小
int _size;//顺序表有效元素的个数
}SeqList,*PSeq;
首先我们要先对这个顺序表初始化
void SeqListInit(PSeq ps, int capacity) {
ps->_array = (DataType*)malloc(sizeof(DataType)*capacity);
if (ps->_array == NULL) {//对申请空间进行判断,看是否申请成功;
assert(0);
return;
}
ps->_capacity = capacity;
ps->_size = 0;//初始化的时候,顺序表中的元素就是0;
}
对顺序表进行增加元素的操作(头插一个元素,尾插一个元素,任意地方插一个元素)
//尾插
void SeqListPushBack(PSeq ps, DataType data) {
assert(ps);
//顺序表满的情况
CheckCapacity(ps);
ps->_array[ps->_size] = data;
ps->_size++;
}
//头插
void SeqListPushFront(PSeq ps, DataType data) {
assert(ps);
CheckCapacity(ps);
//将顺序表中所有的元素统一向后搬移一个位置
for (int i = ps->_size; i > 0; --i) {
ps->_array[i] = ps->_array[i-1];
}
//插入元素
ps->_array[0] = data;
ps->_size++;
}
//任意位置插
void SeqListInsert(PSeq ps, int pos, DataType data) {
assert(ps);
if (pos < 0|| pos > ps->_size) {
return;
}
for (int i = ps->_size; i > pos; --i) {
ps->_array[i] = ps->_array[i - 1];
}
ps->_array[pos] = data;
ps->_size++;
}
插入的时候有一个问题就是:如果顺序表中的元素满了,就插不进去了。所以我们在插入之前要对顺序表进行一个检查。
void CheckCapacity(PSeq ps) {
assert(ps);
if (ps->_size == ps->_capacity) {
int newCapacity = ps->_capacity*2;
//申请新空间
int* pTemp = (DataType*)malloc(newCapacity * sizeof(DataType));
if (pTemp == NULL) {
assert(0);
return;
}
//拷贝元素
for (int i = 0; i < ps->_size; ++i) {
pTemp[i] = ps->_array[i];
}
//释放旧空间
free(ps->_array);
//更新参数
ps->_array = pTemp;
ps->_capacity = newCapacity;
}
}
对顺序表进行删除的操作(头删,尾删,任意位置删除)
//尾删
void SeqListPopBack(PSeq ps) {
assert(ps);
if (SeqListEmpty(ps)) {
return;
}
ps->_size--;
SeqListErase(ps, ps->_size - 1);
}
//头删
void SeqListPopFront(PSeq ps) {
assert(ps);
for (int i = 0; i < ps->_size-1; ++i) {
ps->_array[i] = ps->_array[i+1];
}
ps->_size--;
}
//任意地方删除
void SeqListErase(PSeq ps, int pos) {
assert(ps);
if (pos < 0 || pos >= ps->_size) {
return;
}
for (int i = pos; i < ps->_size-1; ++i) {
ps->_array[i] = ps->_array[i + 1];
}
ps->_size--;
}
对顺序表进行查找
int SeqListFind(PSeq ps, DataType data) {
assert(ps);
for (int i = 0; i < ps->_size; ++i) {
if (ps->_array[i] == data) {
return i;
}
}
return -1;
}
移除顺序表中所有值为data的元素
void SeqListRemoveAll(PSeq ps, DataType data) {
assert(ps);
int pos = -1;
while (-1 != (pos = SeqListFind(ps, data))
{
SeqListErase(ps,pos);
}//时间复杂度o(n^2),算法要进行优化。
}
//时间复杂度o(n),空间复杂度o(1).
void SeqListRemoveAll(PSeq ps, DataType data) {
assert(ps);
int count = 0;
for (int i = 0; i < ps->_size; ++i) {
if (ps->_array[i] == data) {
count++;
} else {
ps->_array[i - count] = ps->_array[i];
}
}
ps->_size -= count;
}
对顺序表进行清空操作
void SeqListClear(PSeq ps) {
assert(ps);
ps->_size = 0;
}
顺序表的整个程序如下
//SeqList.h头文件的代码
#pragma once
typedef int DataType;
//#define MAX_SIZE 100
typedef struct SeqList {
DataType* _array;//用来存储顺序表中元素
int _size;//顺序表中有效元素的个数
int _capacity;///数组所指向空间的大小是多大也就是顺序表的总大小
}SeqList,*PSeq;
void SeqListInit(PSeq ps, int capacity);
void SeqListPushBack(PSeq ps, DataType data);
void SeqListPopBack(PSeq ps);
int SeqListEmpty(PSeq ps);
void SeqListPushFront(PSeq ps, DataType data);
void SeqListPopFront(PSeq ps);
void SeqListInsert(PSeq ps, int pos, DataType data);
void SeqListErase(PSeq ps, int pos);
int SeqListFind(PSeq ps, DataType data);
int SeqListSize(PSeq ps);
int SeqListCapacity(PSeq ps);
void SeqListClear(PSeq ps);
void SeqListRemove(PSeq ps,DataType data);
void SeqListRemoveAll(PSeq ps, DataType data);
void CheckCapacity(PSeq ps);
void SeqListDestroy(PSeq ps);
void TestSeqList();
//SeqList.c文件代码
#include"SeqList.h"
#include<malloc.h>
#include<assert.h>
#include<stdio.h>
#include<stdlib.h>
void SeqListInit(PSeq ps, int capacity) {
ps->_array = (DataType*)malloc(sizeof(DataType)*capacity);
if (ps->_array == NULL) {
assert(0);
return;
}
ps->_capacity = capacity;
ps->_size = 0;
}
void SeqListPushBack(PSeq ps, DataType data) {
assert(ps);
//顺序表满的情况
CheckCapacity(ps);
ps->_array[ps->_size] = data;
ps->_size++;
}
void SeqListPopBack(PSeq ps) {
assert(ps);
if (SeqListEmpty(ps)) {
return;
}
ps->_size--;
SeqListErase(ps, ps->_size - 1);
}
void CheckCapacity(PSeq ps) {
assert(ps);
if (ps->_size == ps->_capacity) {
int newCapacity = ps->_capacity*2;
//申请新空间
int* pTemp = (DataType*)malloc(newCapacity * sizeof(DataType));
if (pTemp == NULL) {
assert(0);
return;
}
//拷贝元素
for (int i = 0; i < ps->_size; ++i) {
pTemp[i] = ps->_array[i];
}
//释放旧空间
free(ps->_array);
//更新参数
ps->_array = pTemp;
ps->_capacity = newCapacity;
}
}
void SeqListInsert(PSeq ps, int pos, DataType data) {
assert(ps);
if (pos < 0|| pos > ps->_size) {
return;
}
for (int i = ps->_size; i > pos; --i) {
ps->_array[i] = ps->_array[i - 1];
}
ps->_array[pos] = data;
ps->_size++;
}
void SeqListErase(PSeq ps, int pos) {
assert(ps);
if (pos < 0 || pos >= ps->_size) {
return;
}
for (int i = pos; i < ps->_size-1; ++i) {
ps->_array[i] = ps->_array[i + 1];
}
ps->_size--;
}
int SeqListFind(PSeq ps, DataType data) {
assert(ps);
for (int i = 0; i < ps->_size; ++i) {
if (ps->_array[i] == data) {
return i;
}
}
return -1;
}
int SeqListSize(PSeq ps) {
assert(ps);
return ps->_size;
}
int SeqListCapacity(PSeq ps) {
assert(ps);
return ps->_capacity;
}
int SeqListEmpty(PSeq ps) {
assert(ps);
return 0 == ps->_size;
}
void SeqListPushFront(PSeq ps, DataType data) {
assert(ps);
CheckCapacity(ps);
//将顺序表中所有的元素统一向后搬移一个位置
for (int i = ps->_size; i > 0; --i) {
ps->_array[i] = ps->_array[i-1];
}
//插入元素
ps->_array[0] = data;
ps->_size++;
}
void SeqListPopFront(PSeq ps) {
assert(ps);
for (int i = 0; i < ps->_size-1; ++i) {
ps->_array[i] = ps->_array[i+1];
}
ps->_size--;
}
void SeqListClear(PSeq ps) {
assert(ps);
ps->_size = 0;
}
void SeqListRemove(PSeq ps, DataType data) {
SeqListErase(ps, SeqListFind(ps, data));
}
void SeqListRemoveAll(PSeq ps, DataType data) {
/*int pos = -1;
while (-1 != (pos = SeqListFind(ps, data)))
{
SeqListErase(ps,pos);
}
*/
assert(ps);
int count = 0;
for (int i = 0; i < ps->_size; ++i) {
if (ps->_array[i] == data) {
count++;
} else {
ps->_array[i - count] = ps->_array[i];
}
}
ps->_size -= count;
}
void SeqListDestroy(PSeq ps) {
if (ps->_array) {
free(ps->_array);
ps->_array = NULL;
ps->_capacity = 0;
ps->_size = 0;
}
}
void SeqListPrint(PSeq ps) {
for (int i = 0; i < ps->_size; ++i) {
printf("%d ", ps->_array[i]);
}
printf("\n");
}
void TestSeqList() {
SeqList s;
int pos = -1;
SeqListInit(&s, 10);
SeqListPushBack(&s, 1);
SeqListPushBack(&s, 2);
SeqListPushBack(&s, 3);
SeqListPushBack(&s, 4);
SeqListPushBack(&s, 5);
SeqListPrint(&s);
SeqListPopBack(&s);
SeqListPrint(&s);
SeqListPushFront(&s, 0);
SeqListPrint(&s);
SeqListPopFront(&s);
SeqListPrint(&s);
SeqListInsert(&s,1,5);
SeqListPrint(&s);
pos = SeqListFind(&s, 5);
if (pos != -1) {
printf("5 is in %d!!!\n", pos);
} else {
printf("5 is not in %d!!!\n", pos);
}
SeqListErase(&s, 1);
pos = SeqListFind(&s, 5);
if (pos != -1) {
printf("5 is in %d!!!\n", pos);
} else {
printf("5 is not in %d!!!\n", pos);
}
SeqListPrint(&s);
printf("size = %d\n", SeqListSize(&s));
printf("capacity = %d\n", SeqListCapacity(&s));
SeqListDestroy(&s);
}
int main() {
TestSeqList();
system("pause");
return 0;
}