本文目标:实现基于静态数组的顺序表的以下基本操作:
- 创建顺序表
#define DyataMaxSize 100 //定义顺序表的大小
typedef int DataType; //定义顺序表元素类型
typedef struct SeqList //定义一个结构体类型变量
{
size_t size; // 有效元素个数
DataType arr[DyataMaxSize];
}SeqList;
- 初始化
思路:只需要将有效元素size设置成0就可以了
//初始化链表
void SeqListInit(SeqList* seq)
{
if (seq == NULL)
return;
else
seq->size = 0; //有效元素置为零
}
- 打印
分析:利用指针seq访问结构体数组元素,然后循环打印即可
//打印链表
void SeqListPrint(SeqList *seq, char *ch)
{
assert(seq);
printf("%s\n", ch);
if ((seq->size)==0)
printf("该链表为空\n");
else
{
size_t i = 0;
for (; i < (seq->size); i++)
{
printf("%3d", seq->arr[i]);
}
printf("\n");
}
}
- 尾插
分析:插入元素时都需要判断顺序是否已经满了,如果顺序表已经满了,则插入失败。尾部插入,由于size的值就是原来顺序表的尾部元素的下标,所以只需要将要插入的值赋值给arr[size]即可,完后记得size要加一,因为有效元素又增加了。
void SeqListPushBack(SeqList* seq, DataType value)
{
assert(seq);
if ((seq->size) >= DyataMaxSize)
printf("顺序表已经满了,无法插入\n");
else
{
seq->arr[seq->size] = value;
++seq->size;
}
}
- 尾删
分析:尾删即删掉最后一个元素,元素个数减一,所以直接将size-1即可
void SeqListPopBack(SeqList* seq)
{
assert(seq);
if ((seq->size) ==0)
printf("顺序表为空,无法删除\n");
else
--(seq->size);
}
- 头插
分析:首先判断顺序表是否已满,其次头插的话,size肯定要先加一,使得插入的元素具有有效性,头插,就必须使原来元素分别往后挪一个空间,将第一个位置空出来,然后才能从头插入新元素,而往后挪的过程肯定得从尾部开始,所以再设置一个临时变量i,并附初值size-1,这里是因为数组下标从0开始,而size从1开始。
void SeqListPushFront(SeqList* seq, DataType value)
{
assert(seq);
if ((seq->size) >= DyataMaxSize)
{
printf("顺序表已经满了,无法插入\n");
}
++seq->size;
size_t i = seq->size - 1;
for (; i > 0; i--)
{
seq->arr[i] = seq->arr[i - 1]; //搬移数据,腾出顺序表首元素空间
}
seq->arr[0] = value;
}
- 头删
分析:头删与头插方法类似,只不过执行相反的操作。
void SeqListPopFront(SeqList* seq)
{
assert(seq);
if ((seq->size) == 0)
{
printf("顺序表为空,无法删除\n");
}
size_t i =0;
for (; i<(seq->size)-1; i++)
{
seq->arr[i] = seq->arr[i+1]; //搬移数据,覆盖顺序表首元素原有空间值
}
--seq->size;
}
- 读任意位置元素
分析:涉及位置时,我们首先得考虑位置是否合法,pos值必须在顺序表有效位置以内,不得越界操作。
如果位置合法,且是正确值时,返回位置为pos-1的元素值,(pos值是从1开始计数,数组下标从0开始)
DataType SeqListGet(SeqList* seq, size_t pos, DataType default_value)
{
assert(seq);
if ((seq->size) == 0)
{
printf("顺序表为空,无法获得\n");
}
if (pos > (seq->size) || pos <= 0)
{
printf("位置不合法,无法获得\n");
}
if (seq->arr[pos-1] != default_value)
return seq->arr[pos-1];
else
return default_value;
}
- 修改任意位置元素
void SeqListSet(SeqList* seq, size_t pos, DataType value)
assert(seq);
if ((seq->size) == 0)
{
printf("顺序表为空,无法修改\n");
}
if (pos > (seq->size) || pos <= 0)
printf("位置不合法\n");
seq->arr[pos - 1] = value;
}
- 查找指定元素值的下标
size_t SeqListFind(SeqList* seq, DataType value)
{
assert(seq);
if ((seq->size) == 0)
{
printf("顺序表为空\n");
return;
}
size_t i = 0;
for (; i < seq->size; i++)
{
if (seq->arr[i] == value)
return i+1;
}
return -1;
}
- 在任意位置插入元素
void SeqListInsert(SeqList* seq, size_t pos, DataType value)
{
assert(seq);
if ((seq->size) == 0)
{
printf("顺序表为空\n");
return;
}
if (pos > seq->size || pos < 1)
{
printf("位置不合法\n");
return;
}
++seq->size-1; //有效元素个数加1
size_t i = seq->size;
for (; i >= pos; i--)
{
seq->arr[i] = seq->arr[i - 1];
}
seq->arr[i] = value;
}
- 在指定位置删除元素
void SeqListErase(SeqList* seq, size_t pos)
{
assert(seq);
if ((seq->size) == 0)
{
printf("顺序表为空\n");
return;
}
if (pos > seq->size || pos < 1)
{
printf("位置不合法\n");
return;
}
size_t i = pos-1;
for (; i<seq->size-1; i++)
{
seq->arr[i] = seq->arr[i + 1];
}
(seq->size)--;
}
- 删除顺序表中指定的值, 如果存在重复元素, 只删除第一个
void SeqListRemove(SeqList* seq, DataType to_delete)
{
assert(seq);
if ((seq->size) == 0)
{
printf("顺序表为空\n");
return;
}
size_t pos = SeqListFind(seq, to_delete);
if (pos == (size_t)-1)
return;
else
SeqListErase(seq, pos);
}
- 获取顺序表元素个数
size_t SeqListSize(SeqList* seq)
{
assert(seq);
if ((seq->size) == 0)
{
printf("顺序表为空\n");
return;
}
return seq->size;
}
- 判定顺序表是否为空
/判定顺序表是否为空,不是返回1,是返回0
int SeqListEmpty(SeqList* seq)
{
assert(seq);
if ((seq->size) == 0)
{
printf("顺序表为空\n");
return 0;
}
else
return 1;
}
- 冒泡排序
void SeqListBubbleSort(SeqList* seq)
{
assert(seq);
if ((seq->size) == 0)
{
printf("顺序表为空\n");
return 0;
}
size_t i = 0;
for (i = 0; i < seq->size - 1; i++)
{
size_t j = 0;
for (; j < seq->size - 1 - i; j++)
{
if (seq->arr[j]>seq->arr[j + 1])
{
size_t tmp = seq->arr[j];
seq->arr[j] = seq->arr[j + 1];
seq->arr[j + 1] = tmp;
}
}
}
}
以下是头文件seqlist.h
#include <stddef.h>
#pragma once
#define DyataMaxSize 100
typedef int DataType;
typedef struct SeqList // 定义一个结构体类型变量
{
size_t size; // 有效元素个数
DataType arr[DyataMaxSize];
}SeqList;
void SeqListInit(SeqList* seq); //初始化
void SeqListPrint(SeqList *seq, char *ch); //打印
void SeqListPushBack(SeqList* seq, DataType value); //尾插
void SeqListPopBack(SeqList* seq); //尾删
void SeqListPushFront(SeqList* seq, DataType value); //头插
void SeqListPopFront(SeqList* seq); //头删
void SeqListSet(SeqList* seq, size_t pos, DataType value); //将顺序表中指定位置的值进行设置
size_t SeqListFind(SeqList* seq, DataType value); //查找顺序表中指定元素的下标
void SeqListInsert(SeqList* seq, size_t pos, DataType value);// 在指定位置插入元素
void SeqListErase(SeqList* seq, size_t pos);// 在指定位置删除元素
void SeqListRemove(SeqList* seq, DataType to_delete); //删除顺序表中指定的值, 如果存在重复元素, 只删除第一个
size_t SeqListSize(SeqList* seq); //获取顺序表元素个数
int SeqListEmpty(SeqList* seq); //判定顺序表是否为空
void SeqListBubbleSort(SeqList* seq); //冒泡排序
DataType SeqListGet(SeqList* seq, size_t pos, DataType default_value); //取顺序表中任意位置的一个元素
test.c文件
#include <stdio.h>
#include "SeqList.h"
void TestSeqListInit()
{
SeqList seq;
SeqListInit(&seq);
}
void TestSeqListPrint()
{
SeqList seq;
SeqListInit(&seq);
SeqListPrint(&seq, "###初始化顺序表###");
}
void TestSeqListPushBack()
{
SeqList seq;
SeqListInit(&seq);
SeqListPushBack(&seq, 1);
SeqListPushBack(&seq, 2);
SeqListPushBack(&seq, 3);
SeqListPushBack(&seq, 4);
SeqListPrint(&seq, "###准备尾插一个元素###");
SeqListPushBack(&seq, 5);
SeqListPrint(&seq, "###尾插一个元素完成###");
}
void TestSeqListPopBack()
{
SeqList seq;
SeqListInit(&seq);
SeqListPushBack(&seq, 1);
SeqListPushBack(&seq, 2);
SeqListPushBack(&seq, 3);
SeqListPushBack(&seq, 4);
SeqListPrint(&seq, "###尾插四个元素###");
SeqListPopBack(&seq);
SeqListPrint(&seq, "###尾删一个元素完成###");
}
头插
void TestSeqListPushFront()
{
SeqList seq;
SeqListInit(&seq);
/*SeqListPrint(&seq, "###初始化顺序表###");*/
SeqListPushBack(&seq, 1);
SeqListPushBack(&seq, 2);
SeqListPushBack(&seq, 3);
SeqListPushBack(&seq, 4);
SeqListPrint(&seq, "###准备头插四个元素###");
SeqListPushFront(&seq,7);
SeqListPushFront(&seq,8);
SeqListPushFront(&seq,9);
SeqListPrint(&seq, "###头插三个元素完成###");
}
头删
void TestSeqListPopFront()
{
SeqList seq;
SeqListInit(&seq);
SeqListPushFront(&seq, 7);
SeqListPushFront(&seq, 8);
SeqListPushFront(&seq, 9);
SeqListPrint(&seq, "###准备头删一个元素###");
SeqListPopFront(&seq);
SeqListPrint(&seq, "###头删一个元素###");
}
void TestSeqListSet() //将顺序表中指定位置的值进行设置
{
SeqList seq;
SeqListInit(&seq);
SeqListPushFront(&seq, 7);
SeqListPushFront(&seq, 8);
SeqListPushFront(&seq, 9);
SeqListPrint(&seq, "### 将第2个位置的值设置成10 ###");
SeqListSet(&seq, 2, 10);
SeqListPrint(&seq, "###设置结束###");
}
void TestSeqListFind()
{
SeqList seq;
SeqListInit(&seq);
SeqListPushFront(&seq, 7);
SeqListPushFront(&seq, 8);
SeqListPushFront(&seq, 9);
SeqListPrint(&seq, "### 查找值为9的下标 ###");
int ret=SeqListFind(&seq, 9);
if (ret > 0)
{
printf("值为7的下标是:%d\n", ret);
}
else
printf("该值不存在\n");
}
void TestSeqListInsert()
{
SeqList seq;
SeqListInit(&seq);
SeqListPushFront(&seq, 7);
SeqListPushFront(&seq, 8);
SeqListPushFront(&seq, 9);
SeqListPushFront(&seq, 10);
SeqListPushFront(&seq, 11);
SeqListPushFront(&seq, 12);
SeqListPrint(&seq, "### 在第3个位置处插入98 ###");
SeqListInsert(&seq, 3, 98);
SeqListPrint(&seq, "### 插入结果 ###");
}
void TestSeqListRrase()
{
SeqList seq;
SeqListInit(&seq);
SeqListPushFront(&seq, 7);
SeqListPushFront(&seq, 8);
SeqListPushFront(&seq, 9);
SeqListPushFront(&seq, 10);
SeqListPushFront(&seq, 11);
SeqListPushFront(&seq, 12);
SeqListPrint(&seq,"###删除第2个元素 ###");
SeqListErase(&seq, 2);
SeqListPrint(&seq, "###删除第2个元素结果 ###");
}
void TestSeqListRemove()
{
SeqList seq;
SeqListInit(&seq);
SeqListPushFront(&seq, 7);
SeqListPushFront(&seq, 8);
SeqListPushFront(&seq, 9);
SeqListPushFront(&seq, 10);
SeqListPushFront(&seq, 11);
SeqListPushFront(&seq, 12);
SeqListPushFront(&seq, 10);
SeqListPrint(&seq, "###删除元素:10 ###");
SeqListRemove(&seq, 10);
SeqListPrint(&seq, "###删除结果 ###");
}
void TestSeqListSize()
{
SeqList seq;
SeqListInit(&seq);
SeqListPushFront(&seq, 7);
SeqListPushFront(&seq, 8);
SeqListPushFront(&seq, 9);
SeqListPushFront(&seq, 10);
SeqListPushFront(&seq, 11);
SeqListPushFront(&seq, 12);
SeqListPushFront(&seq, 10);
SeqListPrint(&seq, "###输出顺序表元素个数###");
size_t count = SeqListSize(&seq);
printf("count=%d", count);
}
void TestSeqListEmpty()
{
SeqList seq;
SeqListInit(&seq);
SeqListPushFront(&seq, 7);
SeqListPushFront(&seq, 8);
SeqListPushFront(&seq, 9);
SeqListPushFront(&seq, 10);
SeqListPushFront(&seq, 11);
SeqListPushFront(&seq, 12);
SeqListPushFront(&seq, 10);
size_t isempty = SeqListEmpty(&seq);
if (isempty > 0)
printf("非空顺序表\n");
else
printf("空顺序表\n");
}
void TestSeqListBubbleSort()
{
SeqList seq;
SeqListInit(&seq);
SeqListPushFront(&seq, 7);
SeqListPushFront(&seq, 8);
SeqListPushFront(&seq, 9);
SeqListPushFront(&seq, 10);
SeqListPushFront(&seq, 11);
SeqListPushFront(&seq, 12);
SeqListPushFront(&seq, 10);
SeqListPrint(&seq, "###冒泡排序###");
SeqListBubbleSort(&seq);
SeqListPrint(&seq, "###冒泡排序结果###");
}
void TestSeqListGet() //取顺序表中任意位置的一个元素
{
SeqList seq;
SeqListInit(&seq);
SeqListPushFront(&seq, 7);
SeqListPushFront(&seq, 8);
SeqListPushFront(&seq, 10);
SeqListPushFront(&seq, 11);
SeqListPushFront(&seq, 12);
SeqListPushFront(&seq, 10);
SeqListPrint(&seq, "###取顺数第二个元素###");
DataType act_value = SeqListGet(&seq, 2, -1);
printf("期望值是12,实际值是:%d", act_value);
}
int main()
{
TestSeqListInit();
TestSeqListPrint();
TestSeqListPushBack();
TestSeqListPopBack();
TestSeqListPushFront();
TestSeqListPopFront();
TestSeqListSet();
TestSeqListFind();
TestSeqListInsert();
TestSeqListRrase();
TestSeqListRemove();
TestSeqListSize();
TestSeqListEmpty();
TestSeqListBubbleSort();
TestSeqListGet();
system("pause");
return 0;
}