数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在⼀种或多种特定关系的数据元素的集合。数据结构反映数据的内部构成,即数据由那部分构成,以什么⽅式构成,以及数据元素之间呈现的结构。也就是能够存储数据;
存储的数据能够方便查找。
1.为什么需要数据结构?
数据结构,能够有效将数据组织和管理在一起。按照我们的⽅式任意对数据进⾏增删改查等操作。最基础的数据结构:数组。但是最基础的数据结构能够提供的操作已经不能完全满⾜复杂算法实现,所以就需要引入
顺序表。
2.顺序表
顺序表的底层结构是数组,对数组的封装,实现了常用的增删改查等接口,这就解决了数组(不能完全满足复杂算法实现)的缺点。
3.顺序表的代码示例:
// SeqList.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int SLDataType;
typedef struct SeqList
{
SLDataType* arr;
int size;
int capacity;
}SL;
//typedef struct SeqList SL;
//顺序表初始化
void SLInit(SL* ps);
//顺序表销毁头部插入
void SLDestroy(SL* ps);
//数据打印
void SLprint(SL sl);
//插入数据之前先看空间够不够
void SLCheckCapacity(SL* ps);
//尾部插入&头部插入
//尾部插入
void SLPushback(SL* ps, SLDataType x);
//头部插入
void SLPushFront(SL* ps, SLDataType x);
//尾部删除&头部删除
//尾部删除
void SLPopBack(SL* ps);
//头部删除
void SLPopFront(SL* ps);
//在指定位置插入数据
void SLInsert(SL* ps, int pos, SLDataType x);
//删除指定位置的数据
void SLErase(SL* ps, int pos);
//查找
int SLFind(SL* ps, SLDataType x);
//SeqList.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
//顺序表初始化
void SLInit(SL* ps)
{
ps->arr = NULL;
ps->size = 0;
ps->capacity = 0;
}
//顺序表销毁
void SLDestroy(SL* ps)
{
if (ps->arr)
{
free(ps->arr);
}
ps->arr = NULL;
ps->size = 0;
ps->capacity = 0;
}
//插入数据之前先看空间够不够
void SLCheckCapacity(SL* ps)
{
if (ps->capacity == ps->size)//空间不够了 需要申请内存
{
int Newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
SLDataType* temp = realloc(ps->arr, Newcapacity * sizeof(SLDataType));
if (temp == NULL)
{
perror("realloc");
exit(1);
//return 1;
}
ps->arr = temp;//内存申请成功
ps->capacity = Newcapacity;
}
}
//数据打印
void SLprint(SL sl)
{
for (int i = 0; i < sl.size; i++)
{
printf("%d ", sl.arr[i]);
}
printf("\n");
}
//尾部插入
void SLPushback(SL* ps, SLDataType x)
{
assert(ps);
SLCheckCapacity(ps);
//ps->arr[ps->size] = x;
//++ps->size;
ps->arr[ps->size++] = x;
}
//头部插入
void SLPushFront(SL* ps, SLDataType x)
{
assert(ps);
SLCheckCapacity(ps);
//先让顺序表中已有的数据整体往后挪动一位
for (int i = ps->size;i>0; i--)
{
ps->arr[i] = ps->arr[i - 1];//arr[1]=arr[0]
}
ps->arr[0] = x;
ps->size++;//长度+1
}
//尾部删除
void SLPopBack(SL* ps)
{
assert(ps);
ps->size--;//--ps->size
}
//头部删除
void SLPopFront(SL* ps)
{
assert(ps);
for (int i = 0; i < ps->size - 1; i++)
{
ps->arr[i] = ps->arr[i + 1];
}
ps->size--;
}
//在指定位置插入数据
void SLInsert(SL* ps, int pos, SLDataType x)
{
assert(ps);
assert(pos >= 0 && pos <= ps->size);
SLCheckCapacity(ps);
for (int i = ps->size; i>pos; i--)
{
ps->arr[i] = ps->arr[i-1];
}
ps->arr[pos] = x;
ps->size++;
}
//删除指定位置的数据
void SLErase(SL* ps, int pos)
{
assert(ps);
assert(pos >= 0 && pos < ps->size);
for (int i = pos; i< ps->size-1; i++)
{
ps->arr[i] = ps->arr[i + 1];
}
ps->size--;
}
//查找
int SLFind(SL* ps, SLDataType x)
{
assert(ps);
for (int i = 0; i < ps->size; i++)
{
if (ps->arr[i] == x)
{
//printf("找到了!\n");
return i;//找到了
}
}
return -1;//找不到
//printf("找不到您所要查找的数据!\n");
}
//SeqList-test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
void test()
{
SL sl;
SLInit(&sl);//初始化
SLPushback(&sl, 1);//尾插一个数字1
SLPushback(&sl, 2);//尾插一个数字1
SLPushback(&sl, 3);//尾插一个数字1
SLPushback(&sl, 4);//尾插一个数字1
SLprint(sl);//1 2 3 4
SLPushFront(&sl, 0); //头插一个数字0
SLprint(sl);//0 1 2 3 4
SLPopBack(&sl);//尾删一个数字
SLprint(sl);//0 1 2 3
SLPopFront(&sl);//头删一个数字
SLprint(sl);//1 2 3
SLInsert(&sl, 0, 0); //在指定位置0处 插入数据(头插)
SLprint(sl);//0 1 2 3
SLInsert(&sl, sl.size, 5); //在指定位置sl.size处 插入数据(尾插)
SLprint(sl);//0 1 2 3 5
SLInsert(&sl, 4, 4); //在指定位置4处 插入数据
SLprint(sl);//0 1 2 3 4 5
SLErase(&sl, 2);//删除指定位置的数据
SLprint(sl);//0 1 3 4 5
int find =SLFind(&sl,5);//查找
//int find =SLFind(&sl,8);//查找
if (find < 0)
{
printf("找不到您所要查找的数据!\n");
}
else
{
printf("找到您所要查找的数据,其下标是%d。\n", find);
}
SLDestroy(&sl);
}
int main()
{
test();
return 0;
}