mysql 线性表_数据结构-线性表之顺序表
線性表
(1)邏輯結(jié)構(gòu)和物理結(jié)構(gòu)
物理結(jié)構(gòu):數(shù)據(jù)元素在內(nèi)存中真實(shí)的存放次序,有可能是連續(xù)存放的,也可能是散落于內(nèi)存里。
邏輯結(jié)構(gòu):為了便于描述數(shù)據(jù)元素之間的關(guān)系,我們想象出數(shù)據(jù)之間應(yīng)該有某種的對(duì)應(yīng)關(guān)系,如果是一對(duì)一就是線性結(jié)構(gòu),不是一對(duì)一那就是非線性結(jié)構(gòu)。
(2)線性表
常見(jiàn)的線性結(jié)構(gòu)就是線性表,所以說(shuō)線性表在邏輯上是線性的,但是在物理上不一定是線性的。常見(jiàn)的線性表有順序表,鏈表,棧,隊(duì)列等。
線性表在物理上存儲(chǔ)時(shí),通常以數(shù)組和鏈?zhǔn)降慕Y(jié)構(gòu)存儲(chǔ)
在這里插入圖片描述
順序表(數(shù)組)
(1)概念
順序表是用一段物理地址連續(xù)的存儲(chǔ)單元依次存儲(chǔ)數(shù)據(jù)元素的線性結(jié)構(gòu),一般情況下采用數(shù)組存儲(chǔ)。在數(shù)組上完成數(shù)據(jù)的增刪查改。
(2)靜態(tài)順序表
頭文件內(nèi)結(jié)構(gòu)體的定義如下
#pragma once
typedef int SLDataType;
#define N 10
struct SeqList
{
SLDataType a[N];//定長(zhǎng)數(shù)組
int size;//有效數(shù)據(jù)個(gè)數(shù),也就是數(shù)組長(zhǎng)度
};
這里一定要注意不要習(xí)慣性的定義結(jié)構(gòu)體,所有的數(shù)據(jù)類型都是int型的,因?yàn)閿?shù)組有時(shí)存放的不會(huì)是int數(shù)據(jù),而是其他數(shù)據(jù),為了結(jié)構(gòu)體通用,防止日后反復(fù)修改,我們要利用typedef和#define進(jìn)行前定義。
在這里插入圖片描述
可以發(fā)現(xiàn)靜態(tài)存儲(chǔ)結(jié)構(gòu),缺點(diǎn)還是很大的,比如說(shuō)在做通訊錄這種東西的時(shí)候,大小無(wú)法準(zhǔn)確控制,所以日常工作中基本不用靜態(tài)的這種結(jié)構(gòu)
(3)動(dòng)態(tài)順序表
A:頭文件內(nèi)結(jié)構(gòu)體的定義如下
#pragma once
typedef int SLDataType;
struct SeqList
{
SLDataType* Array;
int Size;//有效數(shù)據(jù)個(gè)數(shù)
int Capacity;//容量大小
};
動(dòng)態(tài)順序表所變化的是多了一個(gè)表示容量大小的參數(shù),因?yàn)槿绻坏┻_(dá)到容量上限,就可以用relloc擴(kuò)容,使用的是指向一片連續(xù)空間的指針
在這里插入圖片描述
B:操作
*說(shuō)明
這是文件的邏輯
在這里插入圖片描述
下面是測(cè)試文件 SeqList_test.c
#include "SeqList.h"
//測(cè)試插入刪除元素
void Test1(SeqList* ps)
{
SeqListInit(ps);//初始化
SeqListPushBack(ps, 1);
SeqListPushBack(ps, 2);
SeqListPushBack(ps, 3);
SeqListPushBack(ps, 4);
SeqListPushBack(ps, 5);//尾部插入依次元素
SeqListPrint(ps);
SeqListPopBack(&s);
SeqListPopBack(&s);
SeqListPopBack(&s);//尾部依次刪除元素
SeqListPrint(&s);
SeqListPushFront(&s, 9);
SeqListPushFront(&s, 8);
SeqListPushFront(&s, 7);
SeqListPushFront(&s, 6);
SeqListPushFront(&s, 5);//頭部依次插入元素
SeqListPrint(&s);
SeqListPopFront(&s);
SeqListPopFront(&s);
SeqListPopFront(&s);//頭部依次刪除元素
SeqListPrint(&s);
SeqListInsert(&s, 1, 5);
SeqListInsert(&s, 1, 6);//向指定位置插入元素
SeqListPrint(&s);
SeqListErase(&s, 1);
SeqListErase(&s, 1);//把指定位置元素刪除
SeqListPrint(&s);
}
//測(cè)試接受用戶輸入刪除指定元素刪除
void Test2(SeqList* ps)
{
printf("請(qǐng)輸入要?jiǎng)h除的元素\n");
int res = 0;
scanf_s("%d", &res);
int index = SeqListFind(ps, res);
if (index == -1)
printf("沒(méi)有此元素");
else
{
printf("刪除后為\n");
SeqListErase(ps, index);
SeqListPrint(ps);
}
}
int main()
{
SeqList s;
Test1(&s);//測(cè)試插入刪除元素
Test2(&s);//測(cè)試用戶指定元素刪除
return 0;
}
下面是接口聲明"SeqList.h"
#pragma once
#include
#include
#include
typedef int SLDataType;
typedef struct SeqList
{
SLDataType* Array;
int Size;//有效數(shù)據(jù)個(gè)數(shù)
int Capacity;//容量大小
}SeqList;
void SeqListInit(SeqList* ps);//初始化
void SeqListDestory(SeqList* ps);//銷毀
void SeqListPrint(SeqList* ps);//屏幕輸出操作
void SeqListCheckCapacity(SeqList* ps);//檢查容量是否滿了
void SeqListPushBack(SeqList* ps, SLDataType x);//尾插(可以與任意位置插入復(fù)用)
void SeqListPopBack(SeqList* ps);//尾刪除(可以與任意位置刪除復(fù)用)
void SeqListPushFront(SeqList* ps, SLDataType x);//頭插(可以與任意位置插入復(fù)用)
void SeqListPopFront(SeqList* ps);//頭刪(可以與任意位置刪除復(fù)用)
void SeqListInsert(SeqList* ps, int pos, SLDataType x);//任意位置插入
void SeqListErase(SeqList* ps, int pos);//任意位置刪除
int SeqListFind(SeqList* ps, SLDataType x);//使用順序查找法查找某個(gè)元素的位置
int SeqListFindvalue_Bind(SeqList* ps, int pos);//使用二分查找法查找某個(gè)元素的位置
下面是接口實(shí)現(xiàn)"SeqList.c"
#include "SeqList.h"
void SeqListInit(SeqList* ps)//初始化
{
/*也可以這樣申請(qǐng)
s.Size = 0;
s.Array = NULL;
s.Capacity = 0;
*/
ps->Array = (SLDataType*)malloc(sizeof(SLDataType) * 4);
if (ps->Array == NULL)
{
printf("申請(qǐng)失敗\n");
exit(-1);
}
ps->Size = 0;
ps->Capacity = 4;
}
void SeqListDestory(SeqList* ps)//銷毀
{
free(ps->Array);
ps = NULL;
ps->Capacity = ps->Size = 0;
}
void SeqListPrint(SeqList* ps)//打印
{
assert(ps);
for (int i = 0; i < ps->Size; ++i)
{
printf("%d ", ps->Array[i]);
}
printf("\n");
}
void SeqListCheckCapacity(SeqList* ps)//檢查容量是否滿了
{
if (ps->Size == ps->Capacity)
{
ps->Capacity *= 2;
ps->Array = (SLDataType*)realloc(ps->Array, sizeof(SLDataType)*ps->Capacity);
if (ps->Array == NULL)//擴(kuò)容失敗
{
printf("擴(kuò)容失敗\n");
exit(-1);
}
}
}
void SeqListPushBack(SeqList* ps, SLDataType x)//尾插
{
/*尾插就是size位置上的插入
assert(ps);//警告,指針為空
SeqListCheckCapacity(ps);//滿了就擴(kuò)容
ps->Array[ps->Size] = x;//size表示有效個(gè)數(shù),但同時(shí)是下一個(gè)元素的下標(biāo)
ps->Size++;//元素加1
*/
SeqListInsert(ps,ps->Size, x);
}
void SeqListPopBack(SeqList* ps)//尾刪除
{
assert(ps);
ps->Size--;
}
void SeqListPushFront(SeqList* ps, SLDataType x)//頭插
{
/*頭插是0位置上的插入
assert(ps);
SeqListCheckCapacity(ps);//滿了就擴(kuò)容
for (int i = ps->Size-1; i >= 0; i--)//頭插法:從最后一個(gè)元素開(kāi)始,依次向后移,把0的位置空出來(lái)
{
ps->Array[i+1] = ps->Array[i];
}
ps->Array[0] = x;
ps->Size++;
*/
SeqListInsert(ps, 0, x);
}
void SeqListPopFront(SeqList* ps)//頭刪
{
/*頭刪是0位置的刪除
assert(ps);
for (int i = 0; i < ps->Size; i++)
{
ps->Array[i] = ps->Array[i + 1];//刪除時(shí)直接覆蓋即可
}
ps->Size--;
*/
SeqListErase(ps, 0);
}
void SeqListInsert(SeqList* ps, int pos, SLDataType x)//任意位置插入
{
assert(ps);
assert(pos <= ps->Size && pos>= 0);//插入位置有誤
SeqListCheckCapacity(ps);
for (int i = ps->Size - 1; i >= pos; i--)//從插入位置以后依次向后挪動(dòng)
{
ps->Array[i + 1] = ps->Array[i];
}
ps->Array[pos] = x;
ps->Size++;
}
void SeqListErase(SeqList* ps, int pos)//任意位置刪除
{
assert(ps);
assert(pos < ps->Size && pos >= 0);//刪除位置有誤
for (int i = pos; i < ps->Size; i++)
{
ps->Array[i] = ps->Array[i + 1];
}
ps->Size--;
}
int SeqListFind(SeqList* ps, SLDataType x)//順序查找法
{
assert(ps);
int i = 0;
while (iSize)
{
if (ps->Array[i] == x)
return i;
++i;
}
return -1;
}
int SeqListFindvalue_Bind(SeqList* ps, int pos)//二分查找法(前提要排序)
{
int low = 0;
int high = ps->Size - 1;
while (low < high)
{
int mid = (low + high) / 2;
if (pos < ps->Array[mid])
high = mid - 1;
else if (pos > ps->Array[mid])
low = mid + 1;
else
return mid;
}
}
*結(jié)果展示
尾部依次插入五個(gè)元素后,再刪除兩個(gè)元素
[圖片上傳失敗...(image-1f79d9-1612934535403)]
頭部依次插入五個(gè)元素后,再刪除兩個(gè)元素
[圖片上傳失敗...(image-ad641d-1612934535403)]
在原有序列的某個(gè)位置插入兩個(gè)元素,再把元素刪除
[圖片上傳失敗...(image-60a273-1612934535403)]
接受用戶刪除元素
[圖片上傳失敗...(image-e3ead-1612934535403)]
結(jié)語(yǔ)
順序表的優(yōu)點(diǎn)在于:
可以隨機(jī)訪問(wèn)
緩存命中率比較高(這是因?yàn)槠鋽?shù)據(jù)是連續(xù)的,依靠預(yù)加載的就有了優(yōu)勢(shì))
順序表的缺點(diǎn)在于:
中間或者頭部的插入刪除很慢,需要移動(dòng)數(shù)據(jù),時(shí)間復(fù)雜度為O(N)
空間不夠時(shí),增容會(huì)導(dǎo)致一定空間的浪費(fèi)
總結(jié)
以上是生活随笔為你收集整理的mysql 线性表_数据结构-线性表之顺序表的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: mysql 类型 自动转化_自动MySQ
- 下一篇: mysql数据库 数据类型自动编号选哪个