我们对此分为三个文件,两个源文件SeqList.c main.c 和一个头文件SeqList.h。
SeqList.h 中用来包含头文件,定义结构体,和对函数的声明;SeqList.c 中写对函数的实现; main.c 中是主函数和测试函数。
"SeqList.h"
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<stddef.h>
#include<assert.h>
typedef int SLDataType;
typedef struct SeqList{
SLDataType *array;
int capacity; //最大容量
int size; //实际存储容量
}SeqList;
// 初始化
void SeqListInit(SeqList *sl, size_t capacity);
//销毁
void SeqListDestroy(SeqList *sl);
//打印
void SeqListPrint(SeqList *sl);
//检查是否已满,若满则扩容
void CheckCapacity(SeqList *sl);
// 尾插,插入在顺序表的尾部
void SeqListPushBack(SeqList *sl, SLDataType data);
// 头插,插入在顺序表的头部 ([0])
void SeqListPushFront(SeqList *sl, SLDataType data);
// 尾删,删除顺序表尾部的数据
void SeqListPopBack(SeqList *sl);
// 头删,删除顺序表头部的数据
void SeqListPopFront(SeqList *sl);
// 在 pos 所在的下标做数据插入
void SeqListInsert(SeqList *sl, size_t pos, SLDataType data);
// 查找
// 找从 0 开始的第一个
//如果找到了,返回数据所在的下标;如果没找到返回 -1
int SeqListFind(SeqList *sl, SLDataType data);
// 删除 pos 所在的下标数据
void SeqListErase(SeqList *sl, size_t pos);
// 删除第一个遇到的 data
void SeqListRemove(SeqList *sl, SLDataType data);
// 删除所有遇到的 data
void SeqListRemoveAll(SeqList *sl, SLDataType data);
// 修改,pos 所在的下标
void SeqListModify(SeqList *sl, size_t pos, SLDataType data);
//交换
void Swap(a, b);
//冒泡查找
void SeqListBubbleSort(SeqList *sl);
//二分查找(顺序排列情况下)
int SeqListBinarySearch(SeqList *sl, SLDataType data);
"SeqList.c"
#include"SeqList.h"
void SeqListInit(SeqList *sl, size_t capacity)
{
sl->capacity = capacity;
sl->size = 0;
sl->array = (SLDataType *)malloc(capacity * sizeof(SLDataType));
assert(sl->array != NULL);
}
void SeqListDestroy(SeqList *sl)
{
assert(sl != NULL);
//推荐后初始化的先销毁
free(sl->array);
sl->array = NULL;//防御性代码
sl->size = 0;
sl->capacity = 0;
}
void SeqListPrint(SeqList *sl)
{
for (int i = 0; i < sl->size; i++)
{
printf("%d ", sl->array[i]);
}
printf("\n");
}
void CheckCapacity(SeqList *sl)
{
assert(sl != NULL);
//未满,不需扩容
if (sl->size < sl->capacity)
{
return;
}
//满,扩容
//1.申请新空间
int newCapacity = sl->capacity * 2;
SLDataType *newArray =
(SLDataType *)malloc(newCapacity * sizeof(SLDataType));
assert(newArray);
//2.数据搬移至新空间
for (int i = 0; i < sl->size; i++)
{
newArray[i] = sl->array[i];
}
//3.释放旧的空间(防止内存泄漏)
free(sl->array);
//4.保存新的空间
sl->array = newArray;
sl->capacity = newCapacity;
}
void SeqListPushBack(SeqList *sl, SLDataType data)
{
assert(sl != NULL);
CheckCapacity(sl);
sl->array[sl->size] = data;
sl->size++;
}
void SeqListPushFront(SeqList *sl, SLDataType data)
{
assert(sl != NULL);
CheckCapacity(sl);
//从最后一位开始依次向后挪 下标i size-1 ~ 0
for (int i = sl->size - 1; i >= 0; i--)
{
sl->array[i + 1] = sl->array[i];
}
sl->array[0] = data;
sl->size++;
}
void SeqListPopBack(SeqList *sl)
{
assert(sl != NULL);
assert(sl->size > 0);
sl->size--;
}
void SeqListPopFront(SeqList *sl)
{
assert(sl != NULL);
assert(sl->size > 0);
for (int i = 1; i <= sl->size - 1; i++)
{
sl->array[i - 1] = sl->array[i];
}
sl->size--;
}
void SeqListInsert(SeqList *sl, size_t pos, SLDataType data)
{
assert(sl != NULL);
CheckCapacity(sl);
//下标 pos 有效范围 [0, size] ,当为size时,即直接尾插
assert((int)pos >= 0 && (int)pos <= sl->size);
// i 表示下标,从后往前开始移动 size-1 ~ pos
for (int i = sl->size - 1; i >= (int)pos; i--)
{
sl->array[i + 1] = sl->array[i];
}
sl->array[pos] = data;
sl->size++;
}
int SeqListFind(SeqList *sl, SLDataType data)
{
assert(sl != NULL);
for (int i = 0; i < sl->size; i++)
{
if (sl->array[i] == data)
{
return i;
}
}
return -1;
}
void SeqListErase(SeqList *sl, size_t pos)
{
assert(sl != NULL);
//必须有数据才能删
assert(sl->size > 0);
//下标范围 [0, size-1]
assert((int)pos >= 0 && (int)pos < sl->size);
// i 表示数据下标 pos+1 ~ size-1
for (int i = pos + 1; i <= sl->size - 1; i++)
{
sl->array[i - 1] = sl->array[i];
}
sl->size--;
}
void SeqListRemove(SeqList *sl, SLDataType data)
{
int pos = SeqListFind(sl, data);
if (pos != -1)
{
SeqListErase(sl, pos);
}
}
void SeqListRemoveAll(SeqList *sl, SLDataType data)
{
#if 0 // 时间复杂度 O(n^2)
int pos;
while ((pos = SeqListFind(sl, data)) != -1) { // O(n)
SeqListErase(sl, pos); // O(n)
}
#endif
#if 0 // 时间复杂度 O(n),空间复杂度 O(n)
SLDataType *tempArray = (SLDataType *)malloc(
sizeof(SLDataType)* sl->size);
assert(tempArray);
int j = 0;
for (int i = 0; i < sl->size; i++) {
if (sl->array[i] != data) {
tempArray[j++] = sl->array[i];
}
}
for (int k = 0; k < j; k++) {
sl->array[k] = tempArray[k];
}
sl->size = j;
#endif
// i 控制原数据的下标移动,进行遍历
// j 控制新数据的下标移动,不删除则开始新的排序
int j = 0;
for (int i = 0; i < sl->size; i++)
{
if (sl->array[i] != data)
{
sl->array[j++] = sl->array[i];
}
}
sl->size = j;
}
void SeqListModify(SeqList *sl, size_t pos, SLDataType data)
{
assert(sl);
assert((int)pos >= 0 && (int)pos < sl->size);
sl->array[pos] = data;
}
void Swap(int *a, int *b)
{
int t = *a;
*a = *b;
*b = t;
}
void SeqListBubbleSort(SeqList *sl)
{
assert(sl != NULL);
for (int i = 0; i < sl->size - 1; i++)
{
int flag = 1;
for (int j = 0; j < sl->size - 1 - i; j++)
{
if (sl->array[j] > sl->array[j + 1])
{
Swap(&sl->array[j], &sl->array[j + 1]);
flag = 0;
}
}
if (flag)
{
return;
}
}
}
int SeqListBinarySearch(SeqList *sl, SLDataType data)
{
assert(sl != NULL);
int left = 0;
int right = sl->size - 1;
while (left <= right)
{
int mid = left + (right - left) / 2;
if (sl->array[mid] < data)
{
left = mid + 1;
}
else if (sl->array[mid] > data)
{
right = mid - 1;
}
else
{
return mid;
}
}
return -1;//没找到
}
"main.c"
#include"SeqList.h"
void test()
{
SeqList sl;
SeqListInit(&sl, 3);
SeqListInsert(&sl, 0, 3);
SeqListInsert(&sl, 1, 4);
SeqListInsert(&sl, 2, 5);
SeqListInsert(&sl, 1, 6);
SeqListInsert(&sl, 1, 7);
SeqListInsert(&sl, 0, 3);
SeqListInsert(&sl, 1, 4);
SeqListInsert(&sl, 2, 5);
SeqListPrint(&sl);
SeqListErase(&sl, 1);
SeqListPrint(&sl);
SeqListRemove(&sl, 7);
SeqListPrint(&sl);
SeqListRemoveAll(&sl, 5);
SeqListPrint(&sl);
SeqListModify(&sl, 0, 11);
SeqListPrint(&sl);
SeqListPushBack(&sl, 20);
SeqListPrint(&sl);
SeqListPushFront(&sl, 10);
SeqListPrint(&sl);
SeqListPopBack(&sl);
SeqListPrint(&sl);
SeqListPopFront(&sl);
SeqListPrint(&sl);
SeqListBubbleSort(&sl);
SeqListPrint(&sl);
printf("%d\n", SeqListBinarySearch(&sl, 2));
printf("%d\n", SeqListBinarySearch(&sl, 3));
printf("%d\n", SeqListBinarySearch(&sl, 6));
printf("%d\n", SeqListBinarySearch(&sl, 11));
}
int main()
{
test();
system("pause");
return 0;
}
以上便是我写的对顺序表功能的实现,其中的main.c 文件中的 test 函数是我自己在实现过程中的测试,可以有自己的测试方法,不一定按部就班,只要能对函数功能进行检测即可。