引言
要实现静态顺序表,我们首先需要知道什么是顺序表。
顺序表是指用一段地址连续的存储单元依次存取数据元素的线性结构。
顺序表采用的是连续的地址空间,这是与链表的本质区别。对于连续的地址空间,我们一般采用数组,而数组又分为静态数组和动态数组。我们本次要实现的就是采用静态数组的顺序表。
实现静态顺序表的操作
- 静态顺序表的结构体
typedef char SeqListType;
#define SeqListMaxSize 1000
typedef struct SeqList
{
SeqListType data[SeqListMaxSize];
size_t size;//顺序表中有效的数据个数
}SeqList;
2.静态顺序表的初始化
void SeqListInit(SeqList* seqlist);
初始化首先要考虑的就是要对其合法性进行判定,然后再对数组进行初始化。
代码实现为:
void SeqListInit(SeqList* seqlist) {
if (seqlist == NULL) {
return;//非法输入
}
seqlist->size = 0;
}
测试代码:
void TestInit() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
printf("seqlist.size expect 0, actual %lu\n", seqlist.size);
}
测试结果:
3.尾插
void SeqListPushBack(SeqList* seqlist, SeqListType value);
尾插需要考虑一种特殊情况,就是数组的元素数量大于等于SeqListMaxSize时,顺序表就表示已满,就不能再对其进行尾插处理。
*小知识(拿出笔,摆好小本子,做好小笔记):++seqlist->size 和 seqlist->size++的区别
C语言中区别不大,C++区别就大了,前置++的效率高,后置++不仅要++还要返回一个临时变量,它++后还要返回一个原有的值,原有的值开辟一个临时空间保存原有的结果在与现有的结果++。还相差一个对象的拷贝。*
代码实现:
void SeqListPushBack(SeqList* seqlist, SeqListType value) {
if (seqlist == NULL) {
return;//非法输入
}
if (seqlist->size >= SeqListMaxSize) {
return;//顺序表已经满了
}
seqlist->data[seqlist->size] = value;
++seqlist->size;
return;
}
测试代码:
void TestPushBack() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'd');
SeqListPrintChar(&seqlist, "尾部插入四个元素");
}
测试结果:
4.尾删
void SeqListPopBack(SeqList* seqlist);
需要考虑顺序表为空的情况,顺序表为空时,就没有元素可以进行尾删操作。
代码实现:
void SeqListPopBack(SeqList* seqlist) {
if (seqlist == NULL) {
return;//非法输入
}
if (seqlist->size == 0) {
return;//空顺序表
}
--seqlist->size;
return;
}
测试代码:
void TestPopBack() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'd');
SeqListPopBack(&seqlist);
SeqListPrintChar(&seqlist, "尾部删除一个元素");
}
测试结果:
5.头插
void SeqListPushFront(SeqList* seqlist, SeqListType value);
头插就是在顺序表的第一个元素之前插入一个元素,此时就需要考虑顺序表是否已满的情况了,头插一个元素,其后的所有元素就要向后移动一位,当顺序表已满时,进行头插就会使顺序表原有的元素丢失,因此需要进行判断。
代码实现:
void SeqListPushFront(SeqList* seqlist, SeqListType value) {
if (seqlist == NULL) {
return;//非法输入
}
if (seqlist->size >= SeqListMaxSize) {
return;//顺序表已满
}
++seqlist->size;
size_t i = seqlist->size - 1;
for (; i > 0; --i) {
seqlist->data[i] = seqlist->data[i - 1];
}
seqlist->data[0] = value;
return;
}
测试代码:
void TestPushFront() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'd');
SeqListPushFront(&seqlist, 'x');
SeqListPrintChar(&seqlist, "头部插入四个元素");
}
测试结果:
6.头删
void SeqListPopFront(SeqList* seqlist);
刚好与头插相反,它要考虑顺序表为空的情况,要保证有元素可删。
代码实现:
void SeqListPopFront(SeqList* seqlist) {
if (seqlist == NULL) {
return;//非法输入
}
if (seqlist->size == 0) {
return;//空顺序表
}
size_t i = 0;
for (; i < seqlist->size - 1; ++i) {
seqlist->data[i] = seqlist->data[i + 1];
}
--seqlist->size;
return;
}
测试代码:
void TestPopFront() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'd');
SeqListPopFront(&seqlist);
SeqListPrintChar(&seqlist, "头部删除一个元素");
}
测试结果:
7.在指定位置处插入(pos)
void SeqListInsert(SeqList* seqlist, size_t pos, SeqListType value);
当pos==0时就变为了SeqListPushFront,在指定位置插入元素,其位置前的元素没变化,后面的元素将值付给再后面一个元素。
代码实现:
void SeqListInsert(SeqList* seqlist, size_t pos, SeqListType value) {
if (seqlist == NULL) {
return;//非法输入
}
//pos -> [0, size]
if (pos > seqlist -> size) {
return;//pos越界
}
if (seqlist->size >= SeqListMaxSize) {
return;//顺序表已满
}
if (pos == 0) {
SeqListPushFront(seqlist, value);
return;
}
++seqlist->size;
size_t i = seqlist->size - 1;
for (; i - 1 >= pos; --i) {
seqlist->data[i] = seqlist->data[i - 1];
}
seqlist->data[pos] = value;
return;
}
测试代码:
void TestInsert() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'd');
SeqListInsert(&seqlist, 2, 'x');
SeqListPrintChar(&seqlist, "在下标为2处插入一个元素");
}
测试结果:
8.删除指定位置元素(pos)
void SeqListErase(SeqList* seqlist, size_t pos);
指定位置删除和指定位置插入刚好相反,删除指定位置元素后,指定位置后的下标元素和其前一下标元素进行交换。
void SeqListErase(SeqList* seqlist, size_t pos) {
if (seqlist == NULL) {
return;
}
if (seqlist->size == 0) {
return;//空顺序表
}
if (pos >= seqlist->size) {
return;//pos越界
}
size_t i = pos;
for (; i < seqlist->size - 1; ++i) {
seqlist->data[i] = seqlist->data[i + 1];
}
--seqlist->size;
return;
}
测试代码:
void TestErase() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'd');
SeqListErase(&seqlist, 2);
SeqListPrintChar(&seqlist, "删除下标为2的元素");
}
测试结果:
9.查找指定位置元素(pos)
int SeqListGet(SeqList* seqlist, size_t pos, SeqListType* value);
查找成功返回1,查找失败返回0;
小知识(拿出笔,摆出小本子,做好小笔记):assert和错误处理的区别
assert 不可能出现 触发断言就会崩溃 触发信号
错误处理 可能出现
代码实现:
int SeqListGet(SeqList* seqlist, size_t pos, SeqListType* value) {
if (seqlist == NULL) {
return 0;//非法输入
}
if (pos >= seqlist->size) {
return 0;//非法输入
}
*value = seqlist->data[pos];
return 1;
}
测试代码:
void TestGet(){
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListType value;
int ret = SeqListGet(&seqlist, 2, &value);
printf("value expected c,actual %c\n", value);
printf("ret expected 1, actual %d\n", ret);
}
测试结果
10.设置指定元素的值
int SeqListSet(SeqList* seqlist, size_t pos, SeqListType value);
直接将value赋值给指定下标的元素
代码实现:
int SeqListSet(SeqList* seqlist, size_t pos, SeqListType value) {
if (seqlist == NULL) {
return 0;//非法输入
}
if (pos >= seqlist->size) {
return 0;//非法输入
}
seqlist->data[pos] = value;
return 1;
}
测试代码:
void TestSet() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListSet(&seqlist, 1, 'x');
SeqListType value;
int ret = SeqListGet(&seqlist, 1, &value);
printf("ret expected 1, actual %d\n",ret);
printf("value expected x,actual %c\n", value);
}
测试结果:
11.根据指定的值查找下标
size_t SeqListFind(SeqList* seqlist, SeqListType to_find);
找到返回1,没找到返回-1。
代码实现:
size_t SeqListFind(SeqList* seqlist, SeqListType to_find) {
if (seqlist == NULL) {
return;//非法输入
}
size_t i = 0;
for (; i < seqlist->size; ++i) {
if (seqlist->data[i] == to_find) {
return i;
}
}
return -1;
}
测试代码:
void TestFind() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
size_t pos = SeqListFind(&seqlist, 'x');
printf("pos expected -1, actual %ld\n",pos);
pos = SeqListFind(&seqlist, 'a');
printf("pos expected 1,actual %lu\n", pos);
}
测试结果:
12.删除指定值的元素(只删除第一个)
void SeqListRemove(SeqList* seqlist, SeqListType to_remove);
先通过SeqListFind函数找到指定位置元素的下标,然后再通过SeqListErase函数对其进行删除
代码实现:
void SeqListRemove(SeqList* seqlist, SeqListType to_remove) {
if (seqlist == NULL) {
return;//非法输入
}
size_t pos = SeqListFind(seqlist, to_remove);
if (pos == (size_t)-1) {
return;
}
SeqListErase(seqlist, pos);
return;
}
测试代码:
void TestRemove() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'b');
SeqListRemove(&seqlist, 'b');
SeqListPrintChar(&seqlist, "删除第一个值为b的元素");
}
测试结果:
13.删除所有指定值元素
void SeqListRemoveAll(SeqList* seqlist, SeqListType to_remove);
在SeqListRemove的基础上加上一个while循环,退出条件为pos超出范围。
代码实现:
void SeqListRemoveAll(SeqList* seqlist, SeqListType to_remove) {
if (seqlist == NULL) {
return;
}
while (1) {
size_t pos = SeqListFind(seqlist, to_remove);
if (pos == (size_t)-1) {
break;
}
SeqListErase(seqlist, pos);
}
}
测试代码
void TestRemoveAll() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'b');
SeqListRemoveAll(&seqlist, 'b');
SeqListPrintChar(&seqlist, "删除值为b的元素");
}
测试结果:
14.冒泡排序
void SeqListBubbleSort(SeqList* seqlist);
冒泡排序对每次对第一个元素进行处理,使其与后一个元素进行比较,大于后一个值两个值交换位置,知道找到那个小于后一个元素的元素。
代码实现:
void Swap(SeqListType* a, SeqListType* b) {
SeqListType tmp = *a;
*a = *b;
*b = tmp;
}
void SeqListBubbleSort(SeqList* seqlist) {
if (seqlist == NULL) {
return;
}
if (seqlist->size == 0) {
return;
}
//count 变量表示冒泡的次数
size_t count = 0;
for (; count < seqlist->size; ++count) {
size_t cur = 0;
for (; cur < seqlist->size -1; ++cur) {
if (seqlist->data[cur] > seqlist->data[cur + 1]) {
Swap(&seqlist->data[cur], &seqlist->data[cur+1]);
}
}
}
}
测试代码:
void TestBubbleSort() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'd');
SeqListPushBack(&seqlist, 'e');
SeqListBubbleSort(&seqlist);
SeqListPrintChar(&seqlist, "冒泡排序");
}
测试结果:
15.冒泡排序(升级版)
typedef int(*Cmp)(SeqListType a, SeqListType b);
void SeqListBubbleSortEx(SeqList* seqlist, Cmp cmp);
这个升级版冒泡排序增加了一个规则选项,即可以升序也可以降序,这取决于cmp。
代码实现:
void SeqListBubbleSortEx(SeqList* seqlist, Cmp cmp) {
if (seqlist == NULL) {
return;
}
//count 变量表示冒泡的次数
size_t count = 0;
for (; count < seqlist->size; ++count) {
size_t cur = 0;
for (; cur < seqlist->size - 1; ++cur) {
if (!cmp(seqlist->data[cur] , seqlist->data[cur + 1])) {
Swap(&seqlist->data[cur], &seqlist->data[cur + 1]);
}
}
}
return;
}
测试代码:
int Greater(SeqListType a, SeqListType b) {
return a > b ? 1 : 0;
}
void TestBubbleSortEx() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'd');
SeqListPushBack(&seqlist, 'e');
SeqListBubbleSortEx(&seqlist, Greater);
SeqListPrintChar(&seqlist, "降序冒泡排序");
}
测试结果:
代码总和
//seqlist.c
#include "seqlist.h"
void SeqListInit(SeqList* seqlist) {
if (seqlist == NULL) {
return;//非法输入
}
seqlist->size = 0;
}
void SeqListPushBack(SeqList* seqlist, SeqListType value) {
if (seqlist == NULL) {
return;//非法输入
}
if (seqlist->size >= SeqListMaxSize) {
return;//顺序表已经满了
}
seqlist->data[seqlist->size] = value;
++seqlist->size;
return;
}
void SeqListPopBack(SeqList* seqlist) {
if (seqlist == NULL) {
return;//非法输入
}
if (seqlist->size == 0) {
return;//空顺序表
}
--seqlist->size;
return;
}
void SeqListPushFront(SeqList* seqlist, SeqListType value) {
if (seqlist == NULL) {
return;//非法输入
}
if (seqlist->size >= SeqListMaxSize) {
return;//顺序表已满
}
++seqlist->size;
size_t i = seqlist->size - 1;
for (; i > 0; --i) {
seqlist->data[i] = seqlist->data[i - 1];
}
seqlist->data[0] = value;
return;
}
void SeqListPopFront(SeqList* seqlist) {
if (seqlist == NULL) {
return;//非法输入
}
if (seqlist->size == 0) {
return;//空顺序表
}
size_t i = 0;
for (; i < seqlist->size - 1; ++i) {
seqlist->data[i] = seqlist->data[i + 1];
}
--seqlist->size;
return;
}
void SeqListInsert(SeqList* seqlist, size_t pos, SeqListType value) {
if (seqlist == NULL) {
return;//非法输入
}
//pos -> [0, size]
if (pos > seqlist -> size) {
return;//pos越界
}
if (seqlist->size >= SeqListMaxSize) {
return;//顺序表已满
}
if (pos == 0) {
SeqListPushFront(seqlist, value);
return;
}
++seqlist->size;
size_t i = seqlist->size - 1;
for (; i - 1 >= pos; --i) {
seqlist->data[i] = seqlist->data[i - 1];
}
seqlist->data[pos] = value;
return;
}
void SeqListErase(SeqList* seqlist, size_t pos) {
if (seqlist == NULL) {
return;
}
if (seqlist->size == 0) {
return;//空顺序表
}
if (pos >= seqlist->size) {
return;//pos越界
}
size_t i = pos;
for (; i < seqlist->size - 1; ++i) {
seqlist->data[i] = seqlist->data[i + 1];
}
--seqlist->size;
/*调研下上面这种写法和seqlist->size--的区别
C语言中区别不大,C++区别就大了,前置++的效率高,后置++不仅要++还要返回一个临时变量,它++后还要返回一个原有
的值,原有的值开辟一个临时空间保存原有的结果在与现有的结果++。还相差一个对象的拷贝。
*/
return;
}
//assert 不可能出现 触发断言就会崩溃 触发信号
//错误处理 可能出现
int SeqListGet(SeqList* seqlist, size_t pos, SeqListType* value) {
if (seqlist == NULL) {
return 0;//非法输入
}
if (pos >= seqlist->size) {
return 0;//非法输入
}
*value = seqlist->data[pos];
return 1;
}
int SeqListSet(SeqList* seqlist, size_t pos, SeqListType value) {
if (seqlist == NULL) {
return 0;//非法输入
}
if (pos >= seqlist->size) {
return 0;//非法输入
}
seqlist->data[pos] = value;
return 1;
}
size_t SeqListFind(SeqList* seqlist, SeqListType to_find) {
if (seqlist == NULL) {
return;//非法输入
}
size_t i = 0;
for (; i < seqlist->size; ++i) {
if (seqlist->data[i] == to_find) {
return i;
}
}
return -1;
}
void SeqListRemove(SeqList* seqlist, SeqListType to_remove) {
if (seqlist == NULL) {
return;//非法输入
}
size_t pos = SeqListFind(seqlist, to_remove);
if (pos == (size_t)-1) {
return;
}
SeqListErase(seqlist, pos);
return;
}
void SeqListRemoveAll(SeqList* seqlist, SeqListType to_remove) {
if (seqlist == NULL) {
return;
}
while (1) {
size_t pos = SeqListFind(seqlist, to_remove);
if (pos == (size_t)-1) {
break;
}
SeqListErase(seqlist, pos);
}
}
void Swap(SeqListType* a, SeqListType* b) {
SeqListType tmp = *a;
*a = *b;
*b = tmp;
}
void SeqListBubbleSort(SeqList* seqlist) {
if (seqlist == NULL) {
return;
}
if (seqlist->size == 0) {
return;
}
//count 变量表示冒泡的次数
size_t count = 0;
for (; count < seqlist->size; ++count) {
size_t cur = 0;
for (; cur < seqlist->size -1; ++cur) {
if (seqlist->data[cur] > seqlist->data[cur + 1]) {
Swap(&seqlist->data[cur], &seqlist->data[cur+1]);
}
}
}
}
void SeqListBubbleSortEx(SeqList* seqlist, Cmp cmp) {
if (seqlist == NULL) {
return;
}
//count 变量表示冒泡的次数
size_t count = 0;
for (; count < seqlist->size; ++count) {
size_t cur = 0;
for (; cur < seqlist->size - 1; ++cur) {
if (!cmp(seqlist->data[cur] , seqlist->data[cur + 1])) {
Swap(&seqlist->data[cur], &seqlist->data[cur + 1]);
}
}
}
return;
}
//测试代码
#include <stdio.h>
#include <windows.h>
#define TEST_HEADER printf("\n============%s=============\n",__FUNCTION__)
void SeqListPrintChar(SeqList* seqlist, const char* msg) {
if (seqlist == NULL) {
printf("非法输入");
return;
}
printf("[%s]\n",msg);
size_t i = 0;
for (; i < seqlist->size; ++i) {
printf("[%c] ", seqlist ->data[i]);
}
printf("\n");
}
int Greater(SeqListType a, SeqListType b) {
return a > b ? 1 : 0;
}
void TestBubbleSortEx() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'd');
SeqListPushBack(&seqlist, 'e');
SeqListBubbleSortEx(&seqlist, Greater);
SeqListPrintChar(&seqlist, "降序冒泡排序");
}
void TestInit() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
printf("seqlist.size expect 0, actual %lu\n", seqlist.size);
}
void TestPushBack() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'd');
SeqListPrintChar(&seqlist, "尾部插入四个元素");
}
void TestPopBack() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'd');
SeqListPopBack(&seqlist);
SeqListPrintChar(&seqlist, "尾部删除一个元素");
}
void TestPushFront() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'd');
SeqListPushFront(&seqlist, 'x');
SeqListPrintChar(&seqlist, "头部插入四个元素");
}
void TestPopFront() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'd');
SeqListPopFront(&seqlist);
SeqListPrintChar(&seqlist, "头部删除一个元素");
}
void TestInsert() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'd');
SeqListInsert(&seqlist, 2, 'x');
SeqListPrintChar(&seqlist, "在下标为2处插入一个元素");
}
void TestErase() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'd');
SeqListErase(&seqlist, 2);
SeqListPrintChar(&seqlist, "删除下标为2的元素");
}
void TestGet(){
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListType value;
int ret = SeqListGet(&seqlist, 2, &value);
printf("value expected c,actual %c\n", value);
printf("ret expected 1, actual %d\n", ret);
}
void TestSet() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListSet(&seqlist, 1, 'x');
SeqListType value;
int ret = SeqListGet(&seqlist, 1, &value);
printf("ret expected 1, actual %d\n",ret);
printf("value expected x,actual %c\n", value);
}
void TestFind() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
size_t pos = SeqListFind(&seqlist, 'x');
printf("pos expected -1, actual %ld\n",pos);
pos = SeqListFind(&seqlist, 'a');
printf("pos expected 1,actual %lu\n", pos);
}
void TestRemove() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'b');
SeqListRemove(&seqlist, 'b');
SeqListPrintChar(&seqlist, "删除第一个值为b的元素");
}
void TestRemoveAll() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'b');
SeqListRemoveAll(&seqlist, 'b');
SeqListPrintChar(&seqlist, "删除值为b的元素");
}
void TestBubbleSort() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'd');
SeqListPushBack(&seqlist, 'e');
SeqListBubbleSort(&seqlist);
SeqListPrintChar(&seqlist, "冒泡排序");
}
int main() {
TestInit();
TestPushBack();
TestPopBack();
TestPushFront();
TestPopFront();
TestInsert();
TestErase();
TestGet();
TestSet();
TestFind();
TestRemove();
TestRemoveAll();
TestBubbleSort();
TestBubbleSortEx();
system("pause");
return 0;
}
//seqlist.h
#pragma once
#include <stddef.h>
typedef char SeqListType;
#define SeqListMaxSize 1000
typedef struct SeqList
{
SeqListType data[SeqListMaxSize];
size_t size;
}SeqList;
void SeqListInit(SeqList* seqlist);
/*
往顺序表中插入元素
往哪个顺序表中插入
要插入的元素是什么
*/
void SeqListPushBack(SeqList* seqlist, SeqListType value);
/*
尾删
*/
void SeqListPopBack(SeqList* seqlist);
/*
头插
*/
void SeqListPushFront(SeqList* seqlist, SeqListType value);
/*
头删
*/
void SeqListPopFront(SeqList* seqlist);
/*
*/
void SeqListInsert(SeqList* seqlist, size_t pos, SeqListType value);
/*
删除pos位置的元素
*/
void SeqListErase(SeqList* seqlist, size_t pos);
/*
查找下标为pos的元素的值
*/
int SeqListGet(SeqList* seqlist, size_t pos, SeqListType* value);
/*
给指定的元素设置值
*/
int SeqListSet(SeqList* seqlist, size_t pos, SeqListType value);
/*
根据给定的值查找下标
*/
size_t SeqListFind(SeqList* seqlist, SeqListType to_find);
/*
删除指定元素
*/
void SeqListRemove(SeqList* seqlist, SeqListType to_remove);
void SeqListRemoveAll(SeqList* seqlist, SeqListType to_remove);
void SeqListBubbleSort(SeqList* seqlist);
//如果a 和b 满足比较规则,返回1,否则为0
//比较规则:
//如果是升序排序,a<b
typedef int(*Cmp)(SeqListType a, SeqListType b);
void SeqListBubbleSortEx(SeqList* seqlist, Cmp cmp);