静态顺序表的概念不必多说,
我们可以直接在代码中去体会静态顺序表的特性;
在代码中; 我们展示了如何创建一个顺序表;
并且写出函数对顺序表执行操作,
最终在主函数中调用这些函数以完成我们想要的操作
以下代码均包含在头文件中
头文件命名:list.h
这一部分代码为创建顺序表必要操作
#pragma once //表示只编译一次
#include<stdlib.h>
#include<assert.h>
#include<stdio.h>
#include<string.h>
#include<windows.h>
#define MAX_SIZE (100) //定义一个值来表示顺序表可以存储的最大容量
typedef int DataType;
typedef struct SeqList // 定义一个结构体用来表示一个顺序表
{
DataType array[MAX_SIZE]; // 开辟存储数据的空间
int size; //表示有效数据的个数和当前可用的数组下标
}SeqList; //利用typedef将struct SeqList重命名为SeqList;
我们将要对顺序表执行的操作总览
void SeqListInit(SeqList *pSL); //初始化
void SeqListDestroy(SeqList *pSL); //销毁
void SeqListPrint(SeqList *pSL); //输出顺序表中所有元素
void SeqListPushBack(SeqList *pSL,DataType data); //尾插
void SeqListPushFront(SeqList *pSL, DataType data); //头插
void SeqListPushInsert(SeqList *pSL, int pos,DataType data); //根据下标插
void SeqListPopBack(SeqList *pSL, DataType data); //尾删
void SeqListPopFront(SeqList *pSL, DataType data); //头删
void SeqListErase(SeqList *pSL, int pos); //根据下标删
void SeqListRemove(SeqList *pSL, DataType data); //根据数据删除,只删除遇到的第一个
void SeqListRemoveAll(SeqList *pSL, DataType data); //根据数据删除,删除遇到的所有
void SeqListUpdate(SeqList *pSL, int pos, DataType data); //根据下标更新
int SeqListFind(SeqList *pSL, DataType data);//查询,返回遇到的第一个所查询元素下标,否则返回1
void Sequence(SeqList *pSL); //排序函数(选择排序法),递增
再依次写出操作的具体过程
初始化
销毁:在创建一个顺序表并且调用完成后销毁,可以防止出现内存泄漏问题
输出顺序表中元素
void SeqListInit(SeqList *pSL) //初始化
{
assert(pSL != NULL);
//sizeof(DataType);
pSL->size = 0;
}
void SeqListDestroy(SeqList *pSL) //销毁
{
assert(pSL != NULL);
pSL->size = 0;
}
void SeqListPrint(SeqList *pSL) //输出顺序表
{
int i = 0;
for(;i<pSL->size;i++)
{
printf("%-2d ", pSL->array[i]);
}
printf("\n");
}
插入操作
void SeqListPushBack(SeqList *pSL, DataType data) //尾插
{
assert(pSL != NULL);
assert(pSL->size < MAX_SIZE); //有效数据的个数必须小于顺序表下标最大值
pSL->array[pSL->size] = data;
pSL->size++;
}
void SeqListPushFront(SeqList *pSL, DataType data) //头插
{
assert(pSL != NULL);
assert(pSL->size < MAX_SIZE);
//将已有元素往后搬移一格
int pos;
for (pos = pSL->size - 1; pos >= 0; pos--)//第一种方法:以要搬移的数做循环的指示
{
pSL->array[pos + 1] = pSL->array[pos];
}
/*
int space;
for (space = pSL->size; space > 0; space--)//第二种方法:以要搬到的位置做循环的指示
{
pSL->array[space] = pSL->array[space - 1];
}
*/
/*
int i=0;
for (; i< pSL->size;i++) //第三种方法:以循环次数指示
{
pSL->array[pSL->size-i] = pSL->array[pSL->size - 1-i];
}
*/
pSL->array[0] = data;
pSL->size++;
}
void SeqListPushInsert(SeqList *pSL, int pos, DataType data) //根据下标插
{
assert(pSL != NULL);
assert(pSL->size < MAX_SIZE); //有效数据的个数必须小于顺序表下标最大值
assert(pos >= 0 && pos <= pSL->size); //对插入数据的位置做出限制
//把pos和pos以后位置的元素整体往后搬移一格
int space;
for (space = pSL->size; space > pos; space--) //以要搬到的位置做循环的指示
{
pSL->array[space] = pSL->array[space - 1];
}
pSL->array[pos] = data;
pSL->size++;
}
删除操作
void SeqListPopBack(SeqList *pSL, DataType data) //尾删
{
assert(pSL != NULL);
assert(pSL->size >0);
pSL->size++;
}
void SeqListPopFront(SeqList *pSL, DataType data) //头删
{
assert(pSL != NULL);
assert(pSL->size >0);
//把首元素以后位置的元素整体往前搬移一格
int space=0;
for (; space > pSL->size; space++)//以要搬到的位置做循环的指示
{
pSL->array[space] = pSL->array[space + 1];
}
pSL->size--;
}
void SeqListErase(SeqList *pSL, int pos) //根据下标删
{
assert(pSL != NULL);
assert(pSL->size >0);
assert(pos >= 0 && pos <= pSL->size); //对所删除数据的位置做出限制
//所删除元素下标后面的所有元素整体往前搬移一位
int space;
for (space = pos; space <pSL->size-1; space++)//:以要搬到的位置做循环的指示
{
pSL->array[space] = pSL->array[space + 1];
}
pSL->size--;
}
void SeqListRemove(SeqList *pSL, DataType data) //根据数据删除,只删除遇到的第一个
{
int pos = SeqListFind(pSL, data); //调用查询函数,寻找所查元素的下标
if (pos != -1) { //查询到此元素
SeqListErase(pSL, pos); //调用删除函数删除此元素
}
}
void SeqListRemoveAll(SeqList *pSL, DataType data) //根据数据删除,删除所有遇到的;
{
//第一种方法; 时间复杂度为O(N^2)
int pos;
while (1) {
pos = SeqListFind(pSL, data); // 查
if (pos == -1) {
break;
}
SeqListErase(pSL, pos); // 删
}
/*
//第二种方法;
int pos;
while ((pos = SeqListFind(pSL, data)) != -1){
SeqListErase(pSL, pos);
}
//第三种方法:新开辟一个空间,把原顺序表中不是所要删除的数据依次放入新空间中,结束后,再将
// 新开辟空间中的数据依次拿回原顺序表,在原顺序表中依次排序。
//定义一个以DataType类型地址为内容的指针变量newArray,并为其动态分配大小为pSL->size的空间;
DataType *newArray = (DataType*)malloc(sizeof(DataType)*pSL->size); //拿空间
int i, j, k;
for (i = 0, j = 0; i < pSL->size; i++) { //拿数据
if (pSL->array[i] != data) {
newArray[j] = pSL->array[i];
j++;
}
}
pSL->size = j;
for (k = 0; k < pSL->size; k++) { //还数据
pSL->array[k] = newArray[k];
}
free(newArray); //还空间
// 第四种方法 :直接取代
int i,j;
for (i = 0, j = 0; i < pSL->size; i++) {
if (pSL->array[i] != data) {
pSL->array[j] = pSL->array[i];
j++;
}
}
pSL->size = j;
*/
}
其他操作
根据下标更换数据
查询数据
内部排序
void SeqListUpdate(SeqList *pSL, int pos, DataType data) //根据下标更新数据
{
assert(pSL != NULL);
assert(pos >= 0 && pos < pSL->size); //对所要更新的数据的位置做出限制
pSL->array[pos] = data;
}
int SeqListFind(SeqList *pSL, DataType data) //查询,返回遇到的第一个所查询元素下标,否则返回-1
{
assert(pSL != NULL);
int i;
for (i = 0; i < pSL->size;i++)
{
if (pSL->array[i] == data)
{
return i;
}
}
return -1; //没有查询到此元素;
}
void Swap(DataType *a, DataType *b) //数值交换函数;为选择排序法服务;
{
DataType t = *a;
*a = *b;
*b = t;
}
void Sequence(SeqList *pSL) //排序函数(选择排序法),递增
{
int minSpace = 0; // 用来放找到的最小的数的下标
int maxSpace = pSL->size - 1; // 用来放找到的最大的数的下标
int i; //
int minIndex; //整个数列中([minSpace...maxSpace])找到的最小的数的下标
int maxIndex; //整个数列中找到的最大的数的下标
while (minSpace < maxSpace) {
minIndex = minSpace;
maxIndex = minSpace;
for (i = minSpace; i <= maxSpace; i++) //遍历[minSpace...maxSpace],找到最大数和最小数的下标
{
if (pSL->array[i] < pSL->array[minIndex])
{
minIndex = i;
}
if (pSL->array[i] > pSL->array[maxIndex])
{
maxIndex =i;
}
}
//循环完成后;minIndex就是找到的最小数的下标,maxIndex就是找到的最大数的下标;
Swap(pSL->array+minIndex, pSL->array+minSpace);
if (minSpace == maxIndex) {
maxIndex = minIndex;
}
Swap(pSL->array+maxIndex, pSL->array+maxSpace);
minSpace++;
maxSpace--;
}
}
自此,
我们对静态顺序表的各种操作函数就完成了
接下来我们要在主函数中调用他们,以完成我们想要的操作
主函数定义在源文件中
文件名:list.c
#include"list.h"
int main()
{
SeqList sl; //定义一个顺序表
SeqListInit(&sl);
SeqListPushBack(&sl, 6); //插入6
SeqListPushBack(&sl, 8); //插入8
SeqListPushBack(&sl, 3); //插入3
SeqListPushBack(&sl, 4); //插入4
SeqListPushBack(&sl, 1); //插入1
SeqListPushBack(&sl, 3); //插入3
SeqListPushBack(&sl, 2); //插入2
SeqListPrint(&sl); //输出顺序表
Sequence(&sl); //排序
SeqListPrint(&sl);
SeqListRemoveAll(&sl, 3); //删除所有的3
SeqListPrint(&sl);
SeqListRemoveAll(&sl, 2); //删除所有的2
SeqListPrint(&sl);
SeqListPushFront(&sl, 11); //插入11
SeqListPrint(&sl);
SeqListPushInsert(&sl, 3, 33); //第三位插入33
SeqListPrint(&sl);
SeqListUpdate(&sl, 2, 22); //第二位插入22
SeqListPrint(&sl);
SeqListDestroy(&sl); //销毁顺序表
system("pause");
return 0;
}
输出的结果:
6 8 3 4 1 3 2
1 2 3 3 4 6 8
1 2 4 6 8
1 4 6 8
11 1 4 6 8
11 1 4 33 6 8
11 1 22 33 6 8
请按任意键继续. . .