C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)順序表的進(jìn)階講解
前言
在學(xué)習(xí)鏈表之前先掌握順序表
什么是順序表?
順序表是用一段物理地址連續(xù)的存儲(chǔ)單元依次存儲(chǔ)數(shù)據(jù)元素的線性結(jié)構(gòu)一般情況下采用數(shù)組存儲(chǔ),在數(shù)組上完成數(shù)據(jù)的增刪查改。
順序表一般可分為:
- 1.靜態(tài)順序表:使用定長(zhǎng)數(shù)組存儲(chǔ)。
- 2.動(dòng)態(tài)順序表:使用動(dòng)態(tài)開辟的數(shù)組存儲(chǔ)。
提示:由于靜態(tài)功能有限,這里主要討論動(dòng)態(tài)順序表
一、順序表的構(gòu)造VS功能
1.順序表的構(gòu)造
示例:
typedef int SeqDataType
// 順序表的動(dòng)態(tài)存儲(chǔ)
typedef struct SeqList
{
SeqDataType* a; // 指向動(dòng)態(tài)開辟的數(shù)組
size_t size ; // 有效數(shù)據(jù)個(gè)數(shù)
size_t capicity ; // 容量空間的大小
}SeqList;
這里使用SeqDataType定義是由于我們不知道a是什么類型的數(shù)組,因此我們要靈活運(yùn)用功能就要事先定義SeqDataType的類型(此例為int),以便后續(xù)結(jié)構(gòu)類型改變時(shí)容易操作

2.接口實(shí)現(xiàn)(功能)
// 基本增刪查改接口 // 順序表初始化 void SeqListInit(SeqList* psl, size_t capacity); // 順序表銷毀 void SeqListDestory(SeqList* psl); // 順序表打印 void SeqListPrint(SeqList* psl); // 檢查空間,如果滿了,進(jìn)行增容 void CheckCapacity(SeqList* psl); // 順序表尾插 void SeqListPushBack(SeqList* psl, SLDataType x); // 順序表尾刪 void SeqListPopBack(SeqList* psl); // 順序表頭插 void SeqListPushFront(SeqList* psl, SLDataType x); // 順序表頭刪 void SeqListPopFront(SeqList* psl); // 順序表查找 int SeqListFind(SeqList* psl, SLDataType x);
二、功能具體分析
1.初始化
在實(shí)現(xiàn)具體項(xiàng)目功能之前,要事先做好準(zhǔn)備,即初始化,將其置空,assert函數(shù)下文講解
代碼如下(示例):
void SeqListInit(SeqList* pq)//初始化
{
assert(pq);//斷言,判斷是否可以執(zhí)行1/0
pq->a = NULL;
pq->size = 0;
pq->capacity = 0;
}
2.銷毀
銷毀是在結(jié)束之后需要進(jìn)行的操作,因?yàn)檫@里是動(dòng)態(tài),需要考慮空間釋放,以免造成空間泄露。(先提到銷毀是因?yàn)槠渑c初始化為首位)
代碼如下(示例):
void SeqListDestory(SeqList* pq)
{
assert(pq);
free(pq->a);
pq->a = NULL;
pq->capacity = pq->size = 0;
}
3.檢查size與capacity是否溢出
動(dòng)態(tài)進(jìn)行就是根據(jù)輸入的數(shù)據(jù)改變自身數(shù)組的大小,故我們需要對(duì)溢出的情況進(jìn)行正確的規(guī)避,至于為什么會(huì)溢出,因?yàn)槲覀冊(cè)诔跏蓟臅r(shí)候?qū)⑵淇臻g為0,無(wú)論第一次輸入多少數(shù)據(jù)都會(huì)溢出。
void SeqCheckCapacity(SeqList* pq)
{
if (pq->size == pq->capacity)//滿了,需要增容
{
int newcapacity = pq->capacity == 0 ? 4 : pq->capacity * 2;
//SeqDataType* newA = malloc(sizeof(SeqDataType) * newcapacity);
SeqDataType* newA =realloc(pq->a,sizeof(SeqDataType)* newcapacity);//或者直接擴(kuò)容
if (newA == NULL)
{
printf("realloc fail\n");
exit(-1);
}
pq->a = newA;
pq->capacity = newcapacity;
}
}
習(xí)慣上在擴(kuò)容時(shí)我們習(xí)慣將其放大二倍的操作,由于realloc擴(kuò)容分為兩種情況(這里暫時(shí)不討論),故如果擴(kuò)容失敗我們需要截止,并打印錯(cuò)誤。
4.尾增功能(實(shí)現(xiàn))
先上代碼:
void SeqListPushBack(SeqList* pq, SeqDataType x)
{
assert(pq);
SeqCheckCapacity(pq);
pq->a[pq->size] = x;
pq->size++;
}顧名思義就是在尾部增添內(nèi)容,size正對(duì)應(yīng)有效數(shù)組下標(biāo)的下一位,對(duì)該位置進(jìn)行賦值,最后有效數(shù)組size應(yīng)+1,由于尾增之前我們不知道其capacity是否等于size
故我們需要進(jìn)行檢查seqCheckCapacity,如果相等,則需要擴(kuò)容。
5.打印
void SeqListPrint(SeqList* pq)
{
assert(pq);
for (int i = 0; i < pq->size; ++i)
{
printf("%d ", pq->a[i]);
}
printf("\n");
}這里具體就沒(méi)什么了,只是為了保證程序功能能夠具體完整實(shí)現(xiàn)
其他功能看下面代碼
三、實(shí)現(xiàn)具體功能代碼頁(yè)(SeqList.c)
#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
#include<assert.h>
void SeqListInit(SeqList* pq)//初始化
{
assert(pq);//斷言,判斷是否可以執(zhí)行1/0
pq->a = NULL;
pq->size = 0;
pq->capacity = 0;
}
void SeqListDestory(SeqList* pq)
{
assert(pq);
free(pq->a);
pq->a = NULL;
pq->capacity = pq->size = 0;
}
void SeqCheckCapacity(SeqList* pq)
{
if (pq->size == pq->capacity)//滿了,需要增容
{
int newcapacity = pq->capacity == 0 ? 4 : pq->capacity * 2;
//SeqDataType* newA = malloc(sizeof(SeqDataType) * newcapacity);
SeqDataType* newA =realloc(pq->a,sizeof(SeqDataType)* newcapacity);//或者直接擴(kuò)容
if (newA == NULL)
{
printf("realloc fail\n");
exit(-1);
}
pq->a = newA;
pq->capacity = newcapacity;
}
}
void SeqListPushBack(SeqList* pq, SeqDataType x)
{
assert(pq);
SeqCheckCapacity(pq);
pq->a[pq->size] = x;
pq->size++;
}
void SeqListPrint(SeqList* pq)
{
assert(pq);
for (int i = 0; i < pq->size; ++i)
{
printf("%d ", pq->a[i]);
}
printf("\n");
}
void SeqListPushFront(SeqList* pq, SeqDataType x)
{
assert(pq);
SeqCheckCapacity(pq);
int end = pq->size - 1;
while (end >= 0)
{
pq->a[end + 1] = pq->a[end];
end--;
}
pq->a[0] = x;
pq->size++;
}
void SeqListPopBack(SeqList* pq)
{
assert(pq);
assert(pq->size > 0);
--pq->size;
}
void SeqListPopFront(SeqList* pq);//尾刪暫時(shí)不實(shí)現(xiàn)test.c主函數(shù)代碼頁(yè)
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include"SeqList.h"
void TestSeqList1()
{
SeqList s;
SeqListInit(&s);//?
SeqListPushBack(&s, 1);
SeqListPushBack(&s, 2);
SeqListPushBack(&s, 3);
SeqListPushBack(&s, 4);
SeqListPushBack(&s, 5);
SeqListPushFront(&s, 0);
SeqListPushFront(&s, 0);
SeqListPushFront(&s, 0);
SeqListPushFront(&s, 0);
SeqListPrint(&s);
SeqListPopBack(&s);
SeqListPrint(&s);
SeqListPopBack(&s);
SeqListPrint(&s);
SeqListDestory(&s);//
}
int main()
{
TestSeqList1();
return 0;
}
四.總結(jié)
順序表類型實(shí)現(xiàn)通訊錄后期會(huì)更,此目的是為了捋清楚如何構(gòu)造各項(xiàng)結(jié)構(gòu)與結(jié)構(gòu)之間的關(guān)系->數(shù)據(jù)結(jié)構(gòu),尾刪,首刪,首增功能都較為容易,可以看上部分SeqList.c。此外,assert函數(shù)為斷言,目的是防止出現(xiàn)錯(cuò)誤卻找不到并且執(zhí)行的情況,其引用的頭文件為:assert.h。
到此這篇關(guān)于C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)順序表的進(jìn)階講解的文章就介紹到這了,更多相關(guān)C語(yǔ)言 順序表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
OpenCV計(jì)算輪廓長(zhǎng)度/周長(zhǎng)和面積
這篇文章主要為大家詳細(xì)介紹了OpenCV計(jì)算輪廓長(zhǎng)度/周長(zhǎng)和面積,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06
C++統(tǒng)計(jì)軟件使用時(shí)間代碼示例
這篇文章主要介紹了C++統(tǒng)計(jì)軟件使用時(shí)間的小程序,大家可以參考使用2013-11-11
舉例講解C語(yǔ)言對(duì)歸并排序算法的基礎(chǔ)使用
這篇文章主要介紹了C語(yǔ)言對(duì)歸并排序算法的使用,歸并排序算法的平均事件復(fù)雜度為(n\log n),需要的朋友可以參考下2016-05-05
vs2019配置Qt5開發(fā)環(huán)境(圖文教程)
本文主要介紹了如何使用visual studi2019配置qt5開發(fā)環(huán)境,以及創(chuàng)建qt項(xiàng)目,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12

