目录
存储方式
静态存储:
使用定长数组存储元素
动态存储:
使用动态开辟的数组存储
越界
越界不一定会报错,越界读是一种抽查,设置标志位看是否被修改
代码用例
SeqList.h
#pragma once
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLDataType;
typedef struct SeqList {
SLDataType* a;
SLDataType size;//有效数据
SLDataType capacity;//空间容量
}SL;
//顺序表初始化
void SLInit(SL* ps);
//扩容
void SLCheckCapacity(SL* ps);
//打印
void SLPrint(SL* ps);
//销毁顺序表
void SLDestroy(SL* ps);
//尾插
void SLPushBack(SL* ps, SLDataType x);
//头插
void SLPushFront(SL* ps, SLDataType x);
//尾删
void SLPopBack(SL* ps, int x);
//头删
void SLPopFront(SL* ps, SLDataType x);
//任意下标位置的插入删除
//此处的pos指的是位置而不是下标
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos );
SeqList.c
#define _CRT_SECURE_NO_WARNINGS
#include"SeqList.h"
void SLInit(SL* ps) {
assert(ps);
ps->a = NULL;
ps->capacity = 0;
ps->size = 0;
}
void SLDestroy(SL* ps) {
assert(ps);
if (ps->a != NULL) {
free(ps->a);
ps->a = NULL;
ps->capacity = 0;
ps->size = 0;
}
}
void SLPrint(SL* ps) {
assert(ps);
for (int i = 0; i < ps->size; i++) {
printf("%d ", ps->a[i]);
}
printf("\n");
}
void SLCheckCapacity(SL* ps) {
assert(ps);
int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * newCapacity);
if (tmp == NULL) {
perror("realloc");
return;
}
ps->a = tmp;
ps->capacity = newCapacity;
}
void SLPushBack(SL* ps, SLDataType x) {
assert(ps);
if (ps->size == ps->capacity) {
SLCheckCapacity(ps);
}
ps->a[ps->size++] = x;
//此处说明了size和下标的关系
}
void SLPushFront(SL* ps, SLDataType x) {
assert(ps);
if (ps->size == ps->capacity) {
SLCheckCapacity(ps);
}
//挪动数据
int i = ps->size - 1;
while (i >= 0) {
ps->a[i + 1] = ps->a[i];
--i;
}
//放值
ps->a[0] = x;
ps->size++;
}
void SLPopBack(SL* ps, int x) {
//空了就不进行删除操作
//温柔检查
if (ps->size == 0) {
return;
}
//暴力检查
//断言为真就过了,为假就报错
assert(ps->size > 0);
for (int i = 0; i < x; i++) {
ps->size--;
}
}
void SLPopFront(SL* ps, SLDataType x) {
assert(ps);
//挪动数据
//这里要从前往后挪
for (int i = 0; i < x; i++) {
for (int j = 0; j < ps->size; j++) {
ps->a[i] = ps->a[i + 1];
}
ps->size--;
}
}
void SLInsert(SL* ps, int pos, SLDataType x) {
assert(ps);
assert(pos > 0 && pos <= ps->size);//顺序表连续存储
if (ps->capacity == ps->capacity) {
SLCheckCapacity(ps);
}
int i = ps->size - 1;
while (i < pos) {
ps->a[i + 1] = ps->a[i];
--i;
}
ps->a[pos - 1] = x;
ps->size++;
}
void SLErase(SL* ps, int pos) {
assert(ps);
assert(pos > 0 && pos <= ps->size);
int i = pos - 1;
while (i <= ps->size-2) {
ps->a[i] = ps->a[i + 1];
++i;
}
ps->size--;
}
text.c
#define _CRT_SECURE_NO_WARNINGS
#include"SeqList.h"
void Text() {
SL sl;
SLInit(&sl);
SLPushBack(&sl, 1);
SLPushBack(&sl, 2);
SLPushBack(&sl, 3);
SLPushBack(&sl, 4);
SLPushBack(&sl, 5);
SLPushFront(&sl, 10);
SLPushFront(&sl, 20);
SLPushFront(&sl, 30);
SLPushFront(&sl, 40);
SLPopBack(&sl, 2);
SLPopFront(&sl, 2);
SLInsert(&sl, 3, 100);
SLErase(&sl, 1);
SLPrint(&sl);
SLDestroy(&sl);
}
int main() {
Text();
return 0;
}
去重算法思路
1、排序
2、设置dst和src指针 / 下标,指向第一个元素
3、dst和src相等,++dst
4、dst和src不相等,++src,交换dst和src的值,++dst
也就是dst依次找和src相等的值,留空间去覆盖掉相同的值
相当于dst去遍历链表,src是去覆盖所有要求的数组值的
合并两个有序数组
顺序表问题
1、尾部插入效率不错,头部或者中间插入删除,需要挪动数据,效率低下
2、满了以后只能扩容,扩容有一定消耗,比如两倍扩容就存在一定的空间浪费,五个扩容就存在一定的时间浪费