#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int datetype;
#define MAX_SIZE (100)
typedef struct Sequlist {
datetype arry[MAX_SIZE];
//顺序表相当于一个结构体,一个结构体就是一张表,结构体里面两个成员,一个成员是数组,一个是表示数组实际长度的int型变量
int SIZE;
}Sequlist;
typedef struct Sequlist Sequlist;
//接口函数
//初始化.销毁
//增删查改
//初始化函数设置
void SequlistInit(Sequlist *pT)
{
assert(pT != NULL);
pT->SIZE = 0;
}
//销毁
void Sequlistdestroy(Sequlist *pT)
{
assert(pT);
pT->SIZE = 0;
}
//尾插
void Sequlistpushback(Sequlist *pT, datetype date)
{
assert(pT);
//如果存储满了
if (pT->SIZE >= MAX_SIZE)
{
printf("存储满了");
assert(0);
return;
}
//通常情况
pT->arry[pT->SIZE] = date;
pT->SIZE++;
}
// 头插
void SeqListPushFront(Sequlist *pT, datetype data)
{
assert(pT);
// 特殊情况(满了)
if (pT->SIZE >= MAX_SIZE) {
printf("满了\n");
assert(0);
return;
}
// 现有数据整体往后搬移一格
// i 代表的是位置
for (int i = pT->SIZE; i > 0; i--) {
// 前面是位置 后面是数据
pT->arry[i] = pT->arry[i - 1];
}
// i 代表的是数据
/*
for (int i = pSeq->size - 1; i >= 0; i--) {
pSeq->array[i + 1] = pSeq->array[i];
}
*/
// 插入
pT->arry[0] = data;
pT->SIZE++;
}
void SeqListInsert(Sequlist *pT, int pos, datetype data)
{
assert(pT);
assert(pos >= 0 && pos <= pT->SIZE);
// 特殊情况(满了)
if (pT->SIZE >= MAX_SIZE) {
printf("满了\n");
assert(0);
return;
}
// 1. 数据搬移
// 1) 从后往前 2) i 取 数据 [size - 1, pos]
for (int i = pT->SIZE - 1; i >= pos; i--) {
// 位置 数据
pT->arry[i + 1] = pT->arry[i];
}
// 2. 插入
pT->arry[pos] = data;
pT->SIZE++;
}
// 删
// 尾删
void SeqListPopBack(Sequlist *pSeq)
{
assert(pSeq);
// 特殊情况(空了)
if (pSeq->SIZE <= 0) {
printf("空了\n");
assert(0);
return;
}
// 通常情况
pSeq->SIZE--;
}
// 头删
void SeqListPopFront(Sequlist *pT)
{
assert(pT);
// 特殊情况(空了)
if (pT->SIZE <= 0) {
printf("空了\n");
assert(0);
return;
}
// i 代表的是位置
for (int i = 0; i < pT->SIZE - 1; i++) {
// 前位置 后数据
pT->arry[i] = pT->arry[i + 1];
}
pT->SIZE--;
}
void SeqListErase(Sequlist *pT, int pos)
{
assert(pT);
assert(pos >= 0 && pos < pT->SIZE);
// 特殊情况(空了)
if (pT->SIZE <= 0) {
printf("空了\n");
assert(0);
return;
}
// 数据搬移
// 1) 从前往后 2) i 取位置
for (int i = pos; i <= pT->SIZE - 2; i++) {
pT->arry[i] = pT->arry[i + 1];
}
pT->SIZE--;
}
// 传指针减少空间,不改变值
void SeqListPrint(const Sequlist *pSeq)
{
assert(pSeq != NULL);
for (int i = 0; i < pSeq->SIZE; i++) {
printf("%d ", pSeq->arry[i]);
}
printf("\n");
}
// 使用场景
void Test()
{
// 1.
Sequlist seqList;
SequlistInit(&seqList); // 1. seqList, 2. &seqList // 1). 指针空间更小 2).改变值
// 2.
//SeqList *pSeqList;
//pSeqList = SeqListInit();
Sequlistpushback(&seqList, 1);
Sequlistpushback(&seqList, 2);
Sequlistpushback(&seqList, 3);
Sequlistpushback(&seqList, 4);
SeqListPrint(&seqList);
SeqListPopBack(&seqList);
SeqListPrint(&seqList);
SeqListPushFront(&seqList, 10);
SeqListPushFront(&seqList, 20);
SeqListPushFront(&seqList, 30);
SeqListPushFront(&seqList, 40);
SeqListPrint(&seqList);
SeqListPopFront(&seqList);
SeqListPrint(&seqList);
SeqListInsert(&seqList, 4, 100);
SeqListPrint(&seqList);
SeqListErase(&seqList, 4);
SeqListPrint(&seqList);
}
// 查找
// 找到第一个遇到的数的下标,没找到返回 -1 (更理想返回类型 ssize_t)
int SeqListFind(Sequlist *pSeq, datetype data)
{
// 二分查找(前提是有序)
// 顺序遍历查找
for (int i = 0; i < pSeq->SIZE; i++) {
if (data == pSeq->arry[i]) {
// 找到返回下标
return i;
}
}
// 没找到
return -1;
}
// 删除第二种形态 (根据数据删除)
// 1. 删遇到的第一个数据
void SeqListRemove(Sequlist *pSeq, datetype data)
{
int pos = SeqListFind(pSeq, data);
if (pos == -1) {
// 没找到
return;
}
SeqListErase(pSeq, pos);
}
// 2. 删遇到的所有数据
void SeqListRemoveAll(Sequlist *pSeq, datetype data)
{
// 第一种方式 1 1 1 1 ... 1 1
// 慢 N^N
/*while ((pos = SeqListFind(pSeq, data)) != -1) {
SeqListErase(pSeq, pos);
}*/
#if 0
// 2. 一次遍历删除
// 好处: 一次遍历,时间比较快
// 坏处: 开了新空间,空间大小和 size 有关系
// 1) 开新数组
datatype *newArray = (datatype *)malloc(sizeof(datatype)* pT->SIZE);
int i, j;
for (i = 0, j = 0; i < pT->SIZE; i++) {
if (data != pT->arry[i]) {
newArray[j] = pT->arry[i];
j++;
}
}
// 把数据搬回来
for (i = 0; i < j; i++) {
pT->arry[i] = newArray[i];
}
pT->SIZE = j;
// 释放
free(newArray);
#endif
//
// // 第三种方式
// int i, j;
// for (i = 0, j = 0; i < pT->SIZE; i++) {
// if (data !=pT->arry[i]) {
// pT->arry[j] = pT->arry[i];
// j++;
// }
// }
// pT->SIZE = j;
//}