【數據結構初階】--順序表(二)

?

🔥個人主頁:@草莓熊Lotso

🎬作者簡介:C++研發方向學習者

📖個人專欄:?《C語言》?《數據結構與算法》《C語言刷題集》《Leetcode刷題指南》

??人生格言:生活是默默的堅持,毅力是永久的享受。??

?前言:各位朋友們,從今天開始博主將恢復數據結構與算法專欄的更新,為大家分享數據結構初階相關知識,用C語言與大家一起實現一些數據結構,那么我們這篇文章將會接著上次順序表的初始化繼續往后詳細實現順序表的頭插,尾插,頭刪,尾刪等功能。那么這里特別聲明一下,博主會將這些功能分開實現,最后再單獨為大家呈現本節所有內容的完整代碼。


目錄

一.順序表的尾插

二.順序表的頭插

三.順序表的尾刪?

四.順序表的頭刪

五.代碼展現以及時間復雜度對比

SeqList.h:

SeqList.c:?

test.c:?

尾插,頭插,尾刪,頭刪時間復雜度對比:


一.順序表的尾插

--這里分布實現的時候主要展示SeqList.c文件和test.c文件,頭文件這里就不展示了。

SeqList.c:

//尾插
void SLPushBack(SL* ps, SLTDataType x)
{//空間不夠if (ps->size == ps->capacity){//增容int newCapacity = ps->capacity ==0 ? 4 : 2 * ps->capacity;SLTDataType* tmp = (SLTDataType*)realloc(ps->arr, newCapacity*sizeof(SLTDataType));if (tmp = NULL){perror("realloc");exit(1);}ps->arr = tmp;ps->capacity = newCapacity;}//空間足夠ps->arr[ps->size++] = x;//插入完后,size往后走
}

?重點提示:?

增容:我們一般成倍數增加,最好是兩倍。這樣可以有效降低增容的次數,就算可能會存在空間的浪費,但是不會太多。

我們再來看看在此過程中要注意的一些問題:

為了方便觀察,我們再來實現一個打印順序表的函數,很簡單,這里就不解釋了?

//打印
void SLPrint(SL* ps)
{for (int i = 0; i < ps->size; i++){printf("%d ", ps->arr[i]);}printf("\n");
}

test.c:?

#include"SeqList.h"void test1()
{SL s;SLInit(&s);SLPushBack(&s, 1);//1SLPushBack(&s, 2);//12SLPushBack(&s, 3);//123SLPushBack(&s, 4);//1234SLPrint(&s);//1 2 3 4}int main()
{test1();
}

--測試結果如下,成功打印出了經過4次尾插之后的順序表


二.順序表的頭插

--頭插和尾插都離不開空間的檢查增容,所以我們在實現尾插之前可以直接用一個函數實現空間的檢查,后續需要時直接復用就可以了。

//檢查空間
void SLCheckCapacity(SL*ps)
{//擴容int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;SLdatatype* tmp = (SLdatatype*)realloc(ps->arr, newcapacity * sizeof(SLdatatype));if (tmp == NULL){perror("realloc");exit(1);}ps->arr = tmp;ps->capacity = newcapacity;
}

?SeqList.c:

//頭插
void SLPushFront(SL* ps, SLdatatype x)
{assert(ps);//ps!=NULL//檢查空間是否足夠SLCheckCapacity(ps);//空間足夠for (int i = ps->size; i > 0; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[0] = x;ps->size++;
}

?重點提示:

這里其實沒啥坑了,該說的我們都在前面說過了,值得注意的就是頭插,順序表中的其它元素一定是從后往前的順序向后移動一位,如圖所示。再就是利用assert斷言判斷ps不為空了,用if也可以這里就不演示了。

test.c:?

#include"SeqList.h"void test1()
{SL s;SLInit(&s);SLPushBack(&s, 1);SLPushBack(&s, 2);SLPushBack(&s, 3);SLPushBack(&s, 4);SLPrint(&s);//1 2 3 4SLPushFront(&s, 5);SLPrint(&s);// 5 1 2 3 4
}int main()
{test1();
}

--測試出來也沒啥問題,在前面頭插了一個5。?


三.順序表的尾刪?

--順序表的尾刪其實就很簡單了,大家可以想想我們是使用free釋放掉還是令ps->arr[ps->size-1]=0,然后ps->size--呢?其實兩者都不需要,直接ps->size--就結束了,不需要其它的過程。

?SeqList.c:

//尾刪
void SLPopBack(SL* ps)
{assert(ps && ps->size);ps->size--;
}

重點提示:?

尾刪這里直接就是ps->size--就可以了,不用其它的操作了。這里斷言的時候注意ps->size也不能為0就行,不然刪除不了。

test.c:?

#include"SeqList.h"void test1()
{SL s;SLInit(&s);SLPushBack(&s, 1);SLPushBack(&s, 2);SLPushBack(&s, 3);SLPushBack(&s, 4);SLPrint(&s);//1 2 3 4SLPushFront(&s, 5);SLPrint(&s);// 5 1 2 3 4SLPopBack(&s);SLPopBack(&s);SLPrint(&s);// 5 1 2
}int main()
{test1();
}

--測試之后沒問題,尾刪掉了兩個數據,打印出來結果為5 1 2


四.順序表的頭刪

SeqList.c:

//頭刪
void SLPopFront(SL* ps)
{assert(ps && ps->size);for (int i = 0; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}

重點提示:?

頭刪的斷言和尾刪一樣,值得注意的是我們需要將數據按從前往后的順序依次向前移動一位,注意最后循環的終止條件是i=ps->size-1,所以循環進行的條件就是i<ps->size-1。如圖所示,1覆蓋掉了原來的5。實現了頭刪,刪除完后ps->size--就可以了。

test.c:?

#include"SeqList.h"void test1()
{SL s;SLInit(&s);SLPushBack(&s, 1);SLPushBack(&s, 2);SLPushBack(&s, 3);SLPushBack(&s, 4);SLPrint(&s);//1 2 3 4SLPushFront(&s, 5);SLPrint(&s);// 5 1 2 3 4SLPopBack(&s);SLPopBack(&s);SLPrint(&s);// 5 1 2SLPopFront(&s);SLPrint(&s);//1 2
}int main()
{test1();
}

--測試沒有問題,頭刪掉一個5,最終結果打印出來是正確的


五.代碼展現以及時間復雜度對比

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;//順序表初始化
void SLInit(SL* ps);//打印順序表
void SLPrint(SL* ps);//尾插
void SLPushBack(SL* ps, SLdatatype x);
//頭插
void SLPushFront(SL* ps, SLdatatype x);
//尾刪
void SLPopBack(SL* ps);
//頭刪
void SLPopFront(SL* ps);

SeqList.c:?

#define _CRT_SECURE_NO_WARNINGS
#include"SeqList.h"//初始化
void SLInit(SL* ps)
{ps->arr = NULL;ps->size = 0;ps->capacity = 0;
}//打印
void SLPrint(SL* ps)
{for (int i = 0; i < ps->size; i++){printf("%d ", ps->arr[i]);}printf("\n");
}
//檢查空間
void SLCheckCapacity(SL*ps)
{//擴容int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;SLdatatype* tmp = (SLdatatype*)realloc(ps->arr, newcapacity * sizeof(SLdatatype));if (tmp == NULL){perror("realloc");exit(1);}ps->arr = tmp;ps->capacity = newcapacity;
}//尾插
void SLPushBack(SL* ps, SLdatatype x)
{//檢查空間是否足夠SLCheckCapacity(ps);//空間足夠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];}ps->arr[0] = x;ps->size++;
}//尾刪
void SLPopBack(SL* ps)
{assert(ps && ps->size);ps->size--;
}//頭刪
void SLPopFront(SL* ps)
{assert(ps && ps->size);for (int i = 0; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}

test.c:?

#include"SeqList.h"void test1()
{SL s;SLInit(&s);SLPushBack(&s, 1);SLPushBack(&s, 2);SLPushBack(&s, 3);SLPushBack(&s, 4);SLPrint(&s);//1 2 3 4SLPushFront(&s, 5);SLPrint(&s);// 5 1 2 3 4SLPopBack(&s);SLPopBack(&s);SLPrint(&s);// 5 1 2SLPopFront(&s);SLPrint(&s);//1 2
}int main()
{test1();
}

尾插,頭插,尾刪,頭刪時間復雜度對比:

結論:我們通過對比可以看出順序表的尾插,尾刪的時間復雜度比頭插,頭刪要好很多,所有我們可以看出如果操作尾部數據比較多的話,順序表這個數據結構是比較優秀的。?


往期回顧:

【數據結構初階】--算法復雜度的深度解析

【數據結構初階】--順序表(一)

結語:繼上篇博客中我們實現的動態順序表的初始化后,在本篇中我們完成了順序表的尾插,頭插,尾刪,頭刪這四個接口的實現,那么順序表的實現我們其實還沒完全完成,博主將會在后續的博客中繼續和大家一起實現順序表中指定位置的插入和刪除以及查找和修改這四個接口,如果文章對你有幫助的話,歡迎評論,點贊,收藏加關注,感謝大家的支持

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/914174.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/914174.shtml
英文地址,請注明出處:http://en.pswp.cn/news/914174.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java中的方法傳參機制

1. 概述Java中的方法傳參機制分為兩種&#xff1a;值傳遞&#xff08;Pass by Value&#xff09; 和 引用傳遞&#xff08;Pass by Reference&#xff09;。然而&#xff0c;Java中所有的參數傳遞都是值傳遞&#xff0c;只不過對于對象來說&#xff0c;傳遞的是對象的引用地址的…

C++——this關鍵字和new關鍵字

一、this 關鍵字1. 什么是 this&#xff1f;this 是 C 中的一個隱式指針&#xff0c;它指向當前對象&#xff08;即調用成員函數的對象&#xff09;&#xff0c;在成員函數內部使用&#xff0c;用于引用調用該函數的對象。每個類的非靜態成員函數內部都可以使用 this。使用 thi…

Python中類靜態方法:@classmethod/@staticmethod詳解和實戰示例

在 Python 中&#xff0c;類方法 (classmethod) 和靜態方法 (staticmethod) 是類作用域下的兩種特殊方法。它們使用裝飾器定義&#xff0c;并且與實例方法 (def func(self)) 的行為有所不同。1. 三種方法的對比概覽方法類型是否訪問實例 (self)是否訪問類 (cls)典型用途實例方法…

FastGPT革命:下一代語言模型的極速進化

本文深度解析FastGPT核心技術架構&#xff0c;涵蓋分布式推理、量化壓縮、硬件加速等前沿方案&#xff0c;包含完整落地實踐指南&#xff0c;助你掌握大模型高效部署的終極武器。引言&#xff1a;當大模型遭遇速度瓶頸2023年&#xff0c;ChatGPT引爆全球AI熱潮&#xff0c;但企…

Geant4 安裝---Ubuntu

安裝工具 C/C工具包 sudo apt install build-essentialCmake sudo apt install -y cmakeccmake sudo apt install -y cmake-curses-gui安裝Qt可視化工具(不需要可視化可以不安裝) sudo apt-get install qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools qtcreator 安裝Ope…

Spring Boot中請求參數讀取方式

目錄 一、前言 二、六種參數讀取方式 1.RequestParam 2.PathVariable 3.RequestBody 4.RequestHeader 5.CookieValue 6.MatrixVariable 三、對比和搭配 1.適用方法類型及建議使用場景 2.建議使用的請求路徑注解 3. 多種參數同時使用 4.同一請求不同方案&#xff1f…

2025華為OD機試真題最新題庫 (B+C+D+E+2025A+2025B卷) + 在線OJ在線刷題使用(C++、Java、Python C語言 JS合集)(正在更新2025B卷,目前已收錄710道)

2025年&#xff0c;已經開始使用AB卷題庫&#xff0c;題目和往期一樣&#xff0c;舊題加新題的組合&#xff0c;有題目第一時間更新&#xff0c;大家可以跟著繼續學習&#xff0c;目前使用復用題較多&#xff0c;可在OJ上直接找到對應的AB卷學習&#xff0c;可以放心學習&#…

分析新舊因子相關性

計算一組新因子、并分析它們與已有因子間的相關性1. 導入庫和初始化環境功能代碼解析數據加載2. 定義新因子計算函數功能代碼解析因子 1&#xff1a;波動率過濾器&#xff08;filter_001_1&#xff09;因子 2&#xff1a;ATR 過濾器&#xff08;filter_001_2&#xff09;因子 3…

Unity Demo——3D平臺跳躍游戲筆記

今天是一個3D平臺跳躍游戲的筆記。我們按照以下分類來對這個項目的代碼進行學習&#xff1a;核心游戲系統 (Core Game Systems)核心游戲系統是IkunOdyssey項目的基礎&#xff0c;負責所有游戲對象&#xff08;如玩家、敵人、道具等&#xff09;的通用行為和物理交互。它通過實體…

【C語言】回調函數、轉移表、qsort 使用與基于qsort改造冒泡排序

文章目錄數組指針/指針數組函數指針函數指針數組函數指針數組用途(轉移表)回調函數qsort函數基于qsort改造冒泡排序源碼數組指針/指針數組 int arr1[5] { 1,2,3,4,5 };int (*p1)[5] &arr1; //p1是數組指針變量int* arr2[5] { 0 }; //arr2是指針數組指針數組是存放指…

vue3 uniapp 使用ref更新值后子組件沒有更新 ref reactive的區別?使用from from -item執行表單驗證一直提示沒有值

遇到這樣一個問題&#xff0c;我有個1個頁面A&#xff0c;一個from表單組件&#xff0c;一個form-item組件&#xff0c; 使用是這樣的&#xff0c;我在父組件A中使用 &#xff0c;執行表單驗證一直提示沒有值咱們先來講一講ref 和reactive的區別 ref 用來創建一個基本類型或單…

PyQt5布局管理(QBoxLayout(框布局))

QBoxLayout&#xff08;框布局&#xff09; 采用QBoxLayout類可以在水平和垂直方向上排列控件&#xff0c;QHBoxLayout和 QVBoxLayout類繼承自QBoxLayout類。 QHBoxLayout&#xff08;水平布局&#xff09; 采用QHBoxLayout類&#xff0c;按照從左到右的順序來添加控件。QHBoxL…

Grok 4作戰圖刷爆全網,80%華人橫掃硅谷!清華上交校友領銜,95后站C位

來源 | 新智元短短兩年&#xff0c;馬斯克Grok 4的橫空出世&#xff0c;讓xAI團隊一舉站上AI之巔。昨日一小時發布會&#xff0c;Grok 4讓所有人大開眼界&#xff0c;直接刷爆了AIME 2025、人類最后的考試&#xff08;HLE&#xff09;兩大基準。這是狂堆20萬GPU才換來的驚人成果…

AI大模型(七)Langchain核心模塊與實戰(二)

Langchain核心模塊與實戰&#xff08;二&#xff09;Langchian向量數據庫檢索Langchian構建向量數據庫和檢索器批量搜索返回與之相似度最高的第一個檢索器和模型結合得到非籠統的答案LangChain構建代理通過代理去調用Langchain構建RAG的對話應用包含歷史記錄的對話生成Langchia…

Flutter基礎(前端教程①-容器和控件位置)

一個紅色背景的 Container垂直排列的 Column 布局中央的 ElevatedButton按鈕下方的白色文本import package:flutter/material.dart;void main() {runApp(const MyApp()); }class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);overrideWidget bu…

CSS flex

目錄 flex-box和flex-item 主軸和副軸 ?編輯 flex-box的屬性 flex-direction flex-wrap flex-flow justify-content ?編輯?align-items align-content flex-item的屬性 flex-basis flex-grow flex-shrink flex flex-box和flex-item 當把一個塊級元素的displ…

【JMeter】執行系統命令

步驟如下&#xff1a; 添加JSP233 Sampler&#xff1a;右擊線程組>添加>取樣器>JSR223 Sampler2.填寫腳本&#xff0c;執行后查看日志。res "ipconfig".execute().text log.info(res)res "python -c \"print(11)\"".execute().text l…

AI Agent開發學習系列 - langchain之memory(1):內存中的短時記憶

內存中的短時記憶&#xff0c;在 LangChain 中通常指 ConversationBufferMemory 這類“對話緩沖記憶”工具。它的作用是&#xff1a;在內存中保存最近的對話歷史&#xff0c;讓大模型能理解上下文&#xff0c;實現連續對話。 對話緩沖記憶”工具 主要特點 只保留最近的對話內容…

uniapp實現微信小程序端圖片保存到相冊

效果圖展示 安裝插件海報畫板導入到項目里面&#xff0c;在頁面直接使用 <template><view><button click"saveToAlbum" class"save-button">保存到相冊</button><image :src"path" mode"widthFix" v-if&qu…

Java生產帶文字、帶邊框的二維碼

Java 生成帶文字、帶邊框的二維碼1、Java 生成帶文字的二維碼1.1、導入jar包1.2、普通單一的二維碼1.2.1、代碼示例1.2.2、效果1.3、帶文字的二維碼1.&#xff13;.&#xff11;、代碼示例1.3.2、效果2、帶邊框的二維碼2.1、代碼示例2.2、帶邊框的二維碼效果 1、Java 生成帶文字…