顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组 上完成数据的增删查改。
顺序表一般可以分为:
1.静态顺序表:使用定长数组存储。
2.动态顺序表:使用动态开辟的数组存储
// 顺序表的静态存储
#define N 100 typedef int SLDataType;
typedef struct SeqList
{
SLDataType array[N]; // 定长数组
size_t size; // 有效数据的个数
}SeqList;
// 顺序表的动态存储
typedef struct SeqList
{
SLDataType* array; // 指向动态开辟的数组
size_t size ; // 有效数据个数
size_t capicity ; // 容量空间的大小
}SeqList;
头文件SeqList.h
#pragma once
//typedef struct SeqList SeqList;
//typedef struct SeqList* PSeqList;
void SeqListInit(PSeq ps, int capacity);
void SeqListPushBack(PSeq ps, DataType data);
void SeqListPopBack(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 SeqListEmpty(PSeq ps);
int SeqListSize(PSeq ps);
int SeqListCapacity(PSeq ps);
void SeqListClear(PSeq ps);
void SeqListRemove(PSeq ps, DataType data);
void SeqListDestroy(PSeq ps);
void CheckCapacity(PSeq ps);
//
void TestSeqList();
顺序表初始化
//顺序表初始化
void SeqListInit(PSeq ps, int capacity)
{
ps->_array = (DataType*)malloc(sizeof(DataType)*capacity);
if (NULL == ps->_array)
{
assert(0);
return;
}
ps->_capacity = capacity;
ps->_size = 0;
}
头插
//头插
void SeqListPushFront(PSeq ps, DataType data)
{
#if 0
assert(ps);
// CheckCapacity(ps);
// 将顺序表中所有的元素统一向后搬移一个位置
for (int i = ps->_size - 1; i >= 0; i--)
{
ps->_array[i+1] = ps->_array[i];
}
// 插入元素
ps->_array[0] = data;
ps->_size++;
#endif
SeqListInsert(ps, 0, data);
}
头删
//头删
void SeqListPopFront(PSeq ps)
{
#if 0
if (SeqListEmpty(ps))
return;
for (int i = 1; i < ps->_size; ++i)
ps->_array[i-1] = ps->_array[i];
ps->_size--;
#endif
SeqListErase(ps, 0);
}
尾插
//尾插
void SeqListPushBack(PSeq ps, DataType data)
{
#if 0
assert(ps);
// 顺序表满时需要扩容
// CheckCapacity(ps);
ps->_array[ps->_size] = data;
ps->_size++;
#endif
SeqListInsert(ps, ps->_size, data);
}
尾删
/尾删
void SeqListPopBack(PSeq ps)
{
#if 0
assert(ps);
if (SeqListEmpty(ps))
return;
ps->_size--;
#endif
SeqListErase(ps, ps->_size - 1);
}
指定位置pos插入
//指定位置pos插入
void SeqListInsert(PSeq ps, int pos, DataType data)
{
assert(ps);
if (pos < 0 || pos > ps->_size)
return;
CheckCapacity(ps);
for (int i = ps->_size - 1; i >= pos; i--)
ps->_array[i+1] = ps->_array[i];
ps->_array[pos] = data;
ps->_size++;
}
指定位置pos删除
//指定位置pos删除
void SeqListErase(PSeq ps, int pos)
{
assert(ps);
if (pos < 0 || pos >= ps->_size)
return;
for (int i = pos + 1; i < ps->_size; ++i)
ps->_array[i-1] = ps->_array[i];
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的元素
// 移除第一个值为data的元素
void SeqListRemove(PSeq ps, DataType data)
{
SeqListErase(ps, SeqListFind(ps, data));
}
移除所有值为data的元素
/ 移除所有值为data的元素
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];
}
}
释放
void SeqListDestroy(PSeq ps)
{
if (ps->_array)
{
free(ps->_array);
ps->_array = NULL;
ps->_capacity = 0;
ps->_size = 0;
}
}
扩容
void CheckCapacity(PSeq ps)
{
assert(ps);
if (ps->_size == ps->_capacity)
{
// 顺序表中已经没有空间了
int newCapacity = ps->_capacity * 2;
// realloc(p, size)
// 申请新空间
int* pTemp = (DataType*)malloc(newCapacity*sizeof(DataType));
if (NULL == pTemp)
{
assert(0);
return;
}
// 拷贝元素 memcpy
for (int i = 0; i < ps->_size; ++i)
pTemp[i] = ps->_array[i];
// 释放旧空间
free(ps->_array);
// 更新
ps->_array = pTemp;
ps->_capacity = newCapacity;
}
}
交换数据(函数)
//交换数据(函数)
void Swap(int* pLeft, int* pRight)
{
int temp = *pLeft;
*pLeft = *pRight;
*pRight = temp;
}
打印顺序表
void SeqListPrint(PSeq ps)
{
for (int i = 0; i < ps->_size; ++i)
printf("%d ", ps->_array[i]);
printf("\n");
}
冒泡排序
oid BubbleSort(PSeq ps)
{
// N---->N-1
for (int i = 0; i < ps->_size - 1; ++i) // 控制冒泡总的趟数
{
int Ischange = 0;
// 冒泡的具体方式:将相邻的两个元素进行比较, 可能需要交换
for (int j = 1; j < ps->_size - i; ++j)
{
if (ps->_array[j-1] > ps->_array[j])
{
Ischange = 1;
Swap(&ps->_array[j-1], &ps->_array[j]);
}
}
if (!Ischange)
return;
}
}
二分查找
int SeqListBInarySearch(PSeq ps,DataType data)
{
assert(ps);
size_t left = 0;
size_t right = ps->_size - 1;
while (left<=right)
{
int mid = left + (right - left) / 2;
if (ps->_array[mid]==data)
{
return mid;
}
if (ps->_array[mid]>x)
{
right = mid - 1;
}
if (ps->_array[mid]<x)
{
left = mid + 1;
}
}
return -1;
}
最后的测试程序
//测试程序
void TestSeqList()
{
SeqList s;
int pos = -1;
SeqListInit(&s, 10);
SeqListPushBack(&s, 1);
SeqListPushBack(&s, 2);
SeqListPushBack(&s, 2);
SeqListPushBack(&s, 4);
SeqListPushBack(&s, 2);
SeqListPushBack(&s, 6);
SeqListPushBack(&s, 7);
SeqListPushBack(&s, 2);
SeqListPushBack(&s, 9);
SeqListPushBack(&s, 2);
printf("size = %d\n", SeqListSize(&s));
printf("capacity = %d\n", SeqListCapacity(&s));
SeqListPrint(&s);
SeqListRemoveAll(&s, 2);
SeqListPrint(&s);
SeqListPushBack(&s, 1);
printf("size = %d\n", SeqListSize(&s));
printf("capacity = %d\n", SeqListCapacity(&s));
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);
}