实现基于静态数组的顺序表的以下基本操作:
1. 初始化
2. 尾插
3. 尾删
4. 头插
5. 头删
6. 读任意位置元素
7. 修改任意位置元素
8. 查找指定元素值的下标
9. 在任意位置插入元素
10.删除顺序表中指定的值, 如果存在重复元素, 只删除第一个
11.删除顺序表中所有的指定的值, 另外要实现一个时间复杂度为 O(N) 的优化版本
12.获取顺序表元素个数
13.判定顺序表是否为空
14.冒泡排序
15.利用回调函数的冒泡排序
在进行以上操作前首先要判断指针是否为空,删除元素前判断顺序表是否为空;插入元素前判断顺序表是否已满,插入或删除元素时注意是否会越界。
seqlist.h
#pragma once//防止头文件重复定义
#include<stdio.h>
#include<stdlib.h>
#define MAX_SIZE 1000//表示数组的最大长度
#define TEST_HEADER printf("\n===========================%s===========================\n", __FUNCTION__);//定义宏,当前函数的函数名
typedef char SeqListType;
typedef struct SeqList{//方便使用结构体名
SeqListType arr[MAX_SIZE];
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,int pos,SeqListType value);//在任意位置上插入(往哪个顺序表插,插入的位置,插入的元素)
void SeqListErase(SeqList *seqlist, int pos);//在任意位置删除
void SeqListGetValue(SeqList *seqlist, int pos);//在任意位置读取元素
void SeqListSetValue(SeqList *seqlist, int pos, SeqListType value);//在任意位置修改元素
size_t SeqListGetPos(SeqList *seqlist, SeqListType value);//查找指定元素值的下标
void SeqListRemove(SeqList *seqlist, SeqListType to_remove);//删除顺序表中指定的值, 如果存在重复元素, 只删除第一个
void SeqListRemoveAll(SeqList *seqlist, SeqListType to_delete); //删除顺序表中所有的指定的值, 另外要实现一个时间复杂度为 O(N) 的优化版本
size_t SeqListSize(SeqList* seqlist);//获取顺序表元素个数
int SeqListEmpty(SeqList* seqlist);//判定顺序表是否为空
void SeqListBubbleSort(SeqList* seqlist);//冒泡排序
void SeqListBubbleSortEx(SeqList* seqlist, int(*cmp)(SeqListType, SeqListType));//利用回调函数的冒泡排序
int char_cmp(const void* p1, const void* p2);
seqlist.c
#include "seqlist.h"
void SeqListInit(SeqList *seqlist){//初始化函数
if (seqlist == NULL){//判断指针是否为空
printf("非法输入\n");
return;
}
seqlist->size = 0;
}
void SeqListPrintChar(SeqList *seqlist, const char *msg){//打印函数
if (seqlist == NULL){
printf("非法输入\n");
return;
}
printf("[%s]\n", msg);
size_t i = 0;
for (; i < seqlist->size; ++i){
printf("[%c] ", seqlist->arr[i]);
}
printf("\n");
}
void SeqListPushBack(SeqList *seqlist, SeqListType value){ //尾插
if (seqlist == NULL){
printf("非法输入\n");
return;
}
if (seqlist->size >= MAX_SIZE){
printf("顺序表已经满了");
return;
}
seqlist->arr[seqlist->size] = value;
++seqlist->size; //更新元素个数
}
void SeqListPopBack(SeqList *seqlist) { //尾删
if (seqlist == NULL){
printf("非法输入\n");
return;
}
if (seqlist->size == 0){
printf("为空顺序表");
return;
}
--seqlist->size; //使最后一个元素无效
return;
}
void SeqListPushFront(SeqList *seqlist, SeqListType value){ //头插
if (seqlist == NULL){
printf("非法输入\n");
return;
}
if (seqlist->size >= MAX_SIZE){
printf("顺序表已经满了");
return;
}
++seqlist->size;
size_t i = seqlist->size - 1;
for (; i > 0 ; i--){ //i-1不能越界( i-1>=0 )
seqlist->arr[i] = seqlist->arr[i-1];
}
seqlist->arr[0] = value;
return;
}
void SeqListPopFront(SeqList *seqlist){//头删
if (seqlist == NULL){
printf("非法输入\n");
return;
}
if (seqlist->size == 0){
printf("为空顺序表");
return;
}
size_t i = 0;
for (; i < seqlist->size - 1; i++){
seqlist->arr[i] = seqlist->arr[i + 1];
}
--seqlist->size;
return;
}
void SeqListInsert(SeqList *seqlist,int pos,SeqListType value) {//在任意位置上插入
if (seqlist == NULL){
printf("非法输入\n");
return;
}
if (seqlist->size >= MAX_SIZE){
printf("顺序表已经满了");
return;
}
if (pos == 0){ //如果要插入的位置为0,引用头插的函数
SeqListPushFront(seqlist,value);
}
++seqlist->size;
int i = seqlist->size - 1;
for (; i - 1 >= pos; i--){
seqlist->arr[i] = seqlist->arr[i - 1];
}
seqlist->arr[pos]=value;
return;
}
void SeqListErase(SeqList *seqlist, int pos){//在任意位置删除
if (seqlist == NULL){
printf("非法输入\n");
return;
}
if (seqlist->size == 0){
printf("为空顺序表");
return;
}
if (pos >= seqlist->size){
return;
}
int i = pos;
for (; i < seqlist->size - 1; i++)
{
seqlist->arr[i] = seqlist->arr[i + 1];
}
--seqlist->size;
return;
}
void SeqListGetValue(SeqList *seqlist, int pos){//在任意位置读取元素
if (seqlist == NULL){
printf("非法输入\n");
return;
}
if (seqlist->size == 0){
printf("为空顺序表");
return;
}
if (pos >= seqlist->size){
printf("越界");
return;
}
printf("要查找的元素为%c\n", seqlist->arr[pos]);
return seqlist->arr[pos];
}
void SeqListSetValue(SeqList *seqlist, int pos, SeqListType value){//在任意位置修改元素
if (seqlist == NULL){
printf("非法输入\n");
return;
}
if (pos >= seqlist->size){
printf("越界");
return;
}
seqlist->arr[pos] = value;
return;
}
size_t SeqListGetPos(SeqList *seqlist, SeqListType value){//查找指定元素值的下标
if (seqlist == NULL){
printf("非法输入\n");
return;
}
size_t i = 0;
for (; i < MAX_SIZE; i++){
if (seqlist->arr[i] == value){
return i;
}
}
return -1;
}
void SeqListRemove(SeqList* seqlist, SeqListType to_remove){//删除顺序表中指定的值, 如果存在重复元素, 只删除第一个
if (seqlist == NULL){
printf("非法输入\n");
return;
}
size_t i = SeqListGetPos(seqlist, to_remove);
if (i < 0){ //如果没有找到
return;
}
SeqListErase(seqlist, i);
return;
}
void SeqListRemoveAll(SeqList* seqlist, SeqListType to_delete){//删除顺序表中所有的指定的值, 另外要实现一个时间复杂度为 O(N) 的优化版本
if (seqlist == NULL){
printf("非法输入\n");
return;
}
size_t i = 0;
for (; i < seqlist->size - 1; i++){
size_t i = SeqListGetPos(seqlist, to_delete);
if (i < 0){ //如果没有找到
return;
}
SeqListErase(seqlist, i);
}
}
size_t SeqListSize(SeqList* seqlist){//获取顺序表元素个数
if (seqlist == NULL){
printf("非法输入\n");
return;
}
if (seqlist->size == 0){
printf("为空顺序表");
return;
}
return seqlist->size;
}
int SeqListEmpty(SeqList* seqlist){//判定顺序表是否为空
if (seqlist == NULL){
printf("非法输入\n");
return;
}
int i = 1;
if (seqlist->size == 0){
return i;
}
return 0;
}
static void swap(SeqListType *a, SeqListType *b)//交换函数
{
SeqListType tmp = *a;
*a = *b;
*b = tmp;
return;
}
void SeqListBubbleSort(SeqList *seqlist){//冒泡排序
if (seqlist == NULL){
printf("非法输入\n");
return;
}
int i= 0;
int j = 0;
int flag = 0;
for (i = 0; i < seqlist->size - 1; i++){ //剩最后一个元素不用比较(冒泡的趟数)
for (j = 0; j < seqlist->size - 1 - i; j++){//每次冒泡确定一个最大的元素(冒泡的过程)
if (seqlist->arr[j] > seqlist->arr[j + 1]){
flag = 1;
swap(&seqlist->arr[j], &seqlist->arr[j + 1]);
}
}
if (flag == 0){
break;
}
}
}
int char_cmp(const void* p1, const void* p2){
return (*(char *)p1 > *(char *)p2);//强转成char*再解引用
}
void SeqListBubbleSortEX(SeqList* seqlist, int(*cmp)(const void*, const void*)){//利用回调函数的冒泡排序
if (seqlist == NULL){
printf("非法输入\n");
return;
}
int i = 0;
int j = 0;
int flag = 0;
for (; i < seqlist->size - 1; i++){
for (; j < seqlist->size - 1 - i; j++){
if (cmp(&(seqlist->arr[j]), &(seqlist->arr[j + 1]))){
flag = 1;
swap(&seqlist->arr[j], &seqlist->arr[j + 1]);
}
}
if (flag == 0){
break;
}
}
}
test.c
#include "seqlist.h"
void TestInit(){//测试函数(单元测试)
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
printf("seqlist.size expect 0,actual %lu\n",seqlist.size);//lu:无符号长整型
}
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);
SeqListPopBack(&seqlist);
SeqListPrintChar(&seqlist, "尾部删除两个元素");
}
void TestPushFront(){
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushFront(&seqlist, 'x');
SeqListPushFront(&seqlist, 'y');
SeqListPrintChar(&seqlist, "头部插入两个元素");
}
void TestPopFront(){
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'd');
SeqListPopFront(&seqlist);
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, 1, 'x');
SeqListPrintChar(&seqlist, "在2位置插入元素'x'");
SeqListInsert(&seqlist, 3, 'y');
SeqListPrintChar(&seqlist, "在4位置插入元素'y'");
}
void TestErase(){
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'd');
SeqListErase(&seqlist,0);
SeqListPrintChar(&seqlist, "在1位置删除元素");
SeqListErase(&seqlist,2);
SeqListPrintChar(&seqlist, "在3位置删除元素");
}
void TestGetValue(){
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'd');
SeqListGetValue(&seqlist, 1);
SeqListPrintChar(&seqlist,"在2的位置读取元素");
}
void TestSetValue() {
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'd');
SeqListSetValue(&seqlist, 1,'x');
SeqListPrintChar(&seqlist, "在2的位置修改元素");
}
void TestGetPos(){
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'd');
SeqListGetPos(&seqlist,'c');
SeqListPrintChar(&seqlist, "指定‘c’元素的下标");
}
void TestRemove(){
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'd');
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, 'd');
SeqListRemoveAll(&seqlist, 'a');
SeqListRemoveAll(&seqlist, 'b');
SeqListPrintChar(&seqlist, "删除指定的两个元素‘a’,'b'");
}
void TestSize(){
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'd');
size_t count = SeqListSize(&seqlist);
printf("count=%lu\n", count);
SeqListPrintChar(&seqlist, "获取元素表中的个数");
}
void TestEmpty(){
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'b');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'd');
size_t i = SeqListEmpty(&seqlist);
printf("i=%lu\n", i);
SeqListPrintChar(&seqlist, "判断顺序表是否为空");
}
void TestBubbleSort(){//冒泡排序
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'd');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'b');
SeqListBubbleSort(&seqlist);
SeqListPrintChar(&seqlist, "冒泡排序");
}
void TestBubbleSortEX(){
TEST_HEADER;
SeqList seqlist;
SeqListInit(&seqlist);
SeqListPushBack(&seqlist, 'a');
SeqListPushBack(&seqlist, 'd');
SeqListPushBack(&seqlist, 'c');
SeqListPushBack(&seqlist, 'b');
SeqListBubbleSortEX(&seqlist,char_cmp);
SeqListPrintChar(&seqlist, "回调函数的冒泡排序");
}
int main(){
TestInit();
TestPushBack();
TestPopBack();
TestPushFront();
TestPopFront();
TestInsert();
TestErase();
TestGetValue();
TestSetValue();
TestGetPos();
TestRemove();
TestRemoveAll();
TestSize();
TestEmpty();
TestBubbleSort();
TestBubbleSortEX();
getchar();
return;
}