【數據結構c實現】順序表實現

文章目錄

  • 線性表
    • 線性表的順序實現
      • 結點結構
      • 結點初始化
      • 增配空間Inc
      • 打印順序表show_list
      • 線性表長度length
      • 尾部插入push_back
      • 頭部插入push_front
      • 尾部刪除pop_back
      • 頭部刪除pop_front
      • 按位置插入insert_pos
      • 按值查找find
      • 按位置刪除delete_pos
      • 按值刪除delete_val
      • 排序sort(冒泡;升序)
      • 逆置resver
      • 清除表clear
      • 銷毀表destroy
      • 合并表merge

線性表

在數據元素的非空有限集中,(1)存在唯一的一個被稱做“第一個”的數據元素;(2)存在唯一的一個被稱做“最后一個”的數據元素;(3)除第一個之外,集合中的每個數據元素均只有一個前驅;(4)除最后一個之外,集合中每個數據元素均只有一個后繼

線性表的順序實現

線性表的順序表示指的是用一組地址連續的存儲單元依次存儲線性表的數據元素。

結點結構

#define SEQLIST_INIT_SIZE 8typedef struct SeqList {ElemType *base; // 線性表首地址int capacity; // 開辟的內存空間int size; // 有效存儲
} SeqList;

結點初始化

開辟出一段空間(給定空間大小)

void InitSeqList(SeqList *list) {list->base = (ElemType *) malloc(sizeof(ElemType) * SEQLIST_INIT_SIZE);//開辟空間assert(list->base != NULL);list->capacity = SEQLIST_INIT_SIZE;list->size = 0;
}

malloc動態內存分配函數,用于申請一塊連續的指定大小的內存塊區域以ElementType *類型返回分配的內存區域地址:格式:指針名=(指針類型*)malloc(sizeof(指針類型)*數據數量)

②如果表達式的結果為“假”,assert()會打印出斷言失敗的信息Assertion failed:...,并調用abort()函數終止程序的執行Process finished with exit code 3;如果表達式的結果為“真”,assert()就什么也不做,程序繼續往后執行

增配空間Inc

1.重新開辟內存空間,并判斷是否增配空間成功,失敗則增配失敗返回false

2.更新結點線性表首地址和開辟的內存空間

3.之后每次插入數據操作前,添加判斷條件:分配給表內存是否足夠。不夠則進行增配空間,增配空間失敗時,才是真正的內存不足

#define INC_SIZE 3bool Inc(SeqList *list) {//對已有的空間進行分配,原來表開辟內存8,進行重新分配,即開辟8+3內存ElemType *newbase = (ElemType *) realloc(list->base, sizeof(ElemType) * (list->capacity + INC_SIZE));if (newbase == NULL) {printf("增配空間失敗,內存不足\n");return false;}list->base = newbase;list->capacity += INC_SIZE;return true;
}

realloc函數指向在堆區重新開辟的內存塊的起始地址:realloc(先前開辟的內存塊的指針--也就是malloc之前申請的那塊內存空間,即需要調整大小的內存空間,新開辟的那塊內存空間的字節數),返回值為調整之后的內存的起始地址

打印順序表show_list

void show_list(SeqList *list) {for (int i = 0; i < list->size; i++) {printf("%d", list->base[i]);}printf("\n");
}

線性表長度length

int length(SeqList *list) {return list->size;
}

尾部插入push_back

插入6 7 9后順序表中數據順序為:6 7 9

1.判斷有效存儲是否小于開辟的內存空間,即判斷開辟的空間是否已滿,滿了不能插入數據

2.通過下標賦值,即插入數據

3.更新順序表有效存儲長度

void push_back(SeqList *list, ElemType x) {if (list->size >= list->capacity && !Inc(list)) {printf("順序表空間已滿,%d不能尾部插入數據\n", x);return;}list->base[list->size] = x;list->size++;
}

頭部插入push_front

插入6 9 1后順序表中數據順序為:1 9 6

1.判斷有效存儲是否小于開辟的內存空間,即判斷開辟的空間是否已滿,滿了不能插入數據

2.size-1即表中最后一個數據的下標,從最后一個數據開始依次向后移動

3.賦值到下標為0的地址,即插入數據

4.更新順序表有效存儲長度

void push_front(SeqList *list, ElemType x) {if (list->size >= list->capacity && !Inc(list)) {printf("順序表空間已滿,%d不能頭部插入數據\n", x);return;}for (int i = list->size; i > 0; i--) {list->base[i] = list->base[i - 1];}list->base[0] = x;list->size++;
}

尾部刪除pop_back

有順序表1 6 9進行尾部刪除后:1 6

1.判斷size是否為0,即表是否為空,空表不能刪除數據

2.有效長度減1

void pop_back(SeqList *list) {if (list->size == 0) {printf("順序表空間已空,不能尾部刪除數據\n");return;}list->size--;
}

頭部刪除pop_front

有順序表5 6 0進行頭部刪除后:6 0

1.判斷size是否為0,即表是否為空,空表不能刪除數據

2.從第二個數據開始,依次往前移動

3.有效長度減1

void pop_front(SeqList *list) {if (list->size == 0) {printf("順序表空間已空,不能頭部刪除數據\n");return;}for (int i = 0; i < list->size - 1; i++) {list->base[i] = list->base[i + 1];}list->size--;
}

按位置插入insert_pos

在順序表5 3 0下標為2的位置插入數據7為:5 3 7 0

1.判斷pos是否正確并小于有效存儲長度,即判斷插入位置是否合法,位置非法不能插入數據

2.判斷有效存儲是否小于開辟的內存空間,即判斷開辟的空間是否已滿,滿了不能插入數據

3.從最后一個數據開始依次向后移動,直到要插入數據的位置移動結束

4.通過下標賦值,即插入數據

5.更新順序表有效存儲長度

void insert_pos(SeqList *list, int pos, ElemType x) {if (pos < 0 || pos > list->size) {printf("插入數據的位置非法,不能插入數據\n");}if (list->size >= list->capacity && !Inc(list)) {printf("順序表空間已滿,%d不能按位置插入數據\n", x);return;}for (int i = list->size; i > pos; i--) {list->base[i] = list->base[i - 1];}list->base[pos] = x;list->size++;
}

特殊情況:當要插入數據的位置==有效存儲長度時,即尾部插入時,不影響效率[特別注意]

按值查找find

(第一個符合條件的)

1.從順序表第一個數據開始向后遍歷

2.每次遍歷判斷該數據是否是要查找的數據,查找成功返回當前下標

3.遍歷結束,即沒查到數據,返回-1

int find(SeqList *list, ElemType key) {for (int i = 0; i < list->size; i++) {if (list->base[i] == key)return i;}return -1;
}

按位置刪除delete_pos

順序表5 3 0刪除位置為1的數據后:5 0

1.判斷pos是否正確并小于有效存儲長度,即判斷刪除位置是否合法,位置非法不能刪除數據

2.從要刪除的位置開始,依次將后一個數據前移

3.更新順序表有效存儲長度

void delete_pos(SeqList *list, int pos) {if (pos < 0 || pos >= list->size)printf("刪除數據的位置非法,不能刪除數據\n");for (int i = pos; i < list->size - 1; i++) {list->base[i] = list->base[i + 1];}list->size--;
}

按值刪除delete_val

順序表5 3 0刪除值為0的數據后:5 3

1.判斷要刪除的數據是否存在,即按值查找,存在得到查找到的數據下標,不存在得到-1

2.判斷返回值是否是-1,是則數據不存在無法刪除,否則按位置刪除

void delete_val(SeqList *list, ElemType key) {int pos = find(list, key);if (pos == -1) {printf("要刪除的數據不存在\n");return;}delete_pos(list, pos);
}

排序sort(冒泡;升序)

順序表5 3 0 1 9 4排序后:0 1 3 4 5 9

1.兩層遍歷,依次比較兩個數據,前面數據大于后面數據則交換

void sort(SeqList *list) {for (int i = 0; i < list->size; i++) {for (int j = 0; j < list->size - i - 1; j++) {if (list->base[j] > list->base[j + 1]) {ElemType tmp = list->base[j];list->base[j] = list->base[j + 1];list->base[j + 1] = tmp;}}}
}

逆置resver

順序表5 3 0 1 9 4逆置后:4 9 1 0 3 5

1.判斷順序表長度是否可進行逆置操作操作,長度為1或0時不需要

2.設置兩個整型指針low和high,分別指向第一個數據和最后一個數據,low指針后移,high指針前移,每次將兩個指針指向的數據對換,直到low指針大于或等于high指針為止

void resver(SeqList *list) {if (list->size == 0 || list->size == 1)return;int low = 0;int high = list->size - 1;ElemType tmp;while (low < high) {tmp = list->base[low];list->base[low] = list->base[high];list->base[high] = tmp;low++;high--;}
}

清除表clear

void clear(SeqList *list) {list->size = 0;
}

銷毀表destroy

void destroy(SeqList *list) {free(list->base);list->base = NULL;list->capacity = 0;list->size = 0;
}

free函數必須和malloc函數同時使用

free只能釋放由malloc動態分配在堆內存的內存,直接在主函數定義結構體變量是分配在棧內存里的內存,所以釋放不了

合并表merge

表A1 2 5 6,表B3 4 7 9,合并后:1 2 3 4 5 6 9

1.設置iaibic三個整型指針,分別用來遍歷表A、B、合并表,開辟存放合并表的內存空間,并判斷是否開辟成功

2.同時遍歷表A和表B,依次判斷指針指向的A、B表的數據大小,將較小的數據放入合并表,每存入一個數據,合并表和被存入的數據所在表的整型指針都向后移一次,直到A、B有一個表遍歷完

3.如果其中一個表遍歷結束,另一個表還有遍歷完的數據,則直接將剩余數據依次存入合并表

4.更新合并表有效存儲長度

void merge(SeqList *lt, SeqList *la, SeqList *lb) {lt->capacity = la->size + la->size;lt->base = (ElemType *) malloc(sizeof(ElemType)*lt->capacity);assert(lt->base != NULL);int ia = 0;int ib = 0;int ic = 0;while(ia<la->size && ib<lb->size){if(la->base[ia] < lb->base[ib])lt->base[ic++] = la->base[ia++];elselt->base[ic++] = lb->base[ib++];}while(ia < la->size){lt->base[ic++] = la->base[ia++];}while(ib < lb->size){lt->base[ic++] = lb->base[ib++];}lt->size = la->size + lb->size;
}

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

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

相關文章

云上業務DDoS與CC攻擊防護實踐

案例背景&#xff1a;DDoS攻擊來勢洶洶&#xff0c;云上業務面臨威脅 某網絡科技有限公司&#xff0c;SaaS化創業公司&#xff0c;業務基于云上開展。其業務主要為各大網站提供安全驗證服務&#xff0c;且市場占有率較高&#xff0c;服務客戶遍布金融、直播、教育、電商等多個領…

【日常總結】mybatis-plus WHERE BINARY 中文查不出來

目錄 一、場景 二、問題 三、原因 四、解決方案 五、拓展&#xff08;全表全字段修改字符集一鍵更改&#xff09; 準備工作&#xff1a;做好整個庫備份 1. 全表一鍵修改 Stage 1&#xff1a;運行如下查詢 Stage 2&#xff1a;復制sql語句 Stage 3&#xff1a;執行即可…

100. 相同的樹(Java)

目錄 解法&#xff1a; 官方解法&#xff1a; 方法一&#xff1a;深度優先搜索 復雜度分析 時間復雜度&#xff1a; 空間復雜度&#xff1a; 方法二&#xff1a;廣度優先搜索 復雜度分析 時間復雜度&#xff1a; 空間復雜度&#xff1a; 給你兩棵二叉樹的根節點 p 和…

L1-028:判斷素數

題目描述 本題的目標很簡單&#xff0c;就是判斷一個給定的正整數是否素數。 輸入格式&#xff1a; 輸入在第一行給出一個正整數N&#xff08;≤ 10&#xff09;&#xff0c;隨后N行&#xff0c;每行給出一個小于231的需要判斷的正整數。 輸出格式&#xff1a; 對每個需要判斷的…

Kotlin(十五) 高階函數詳解

高階函數的定義 高階函數和Lambda的關系是密不可分的。在之前的文章中&#xff0c;我們熟悉了Lambda編程的基礎知識&#xff0c;并且掌握了一些與集合相關的函數式API的用法&#xff0c;如map、filter函數等。另外&#xff0c;我們也了解了Kotlin的標準函數&#xff0c;如run、…

vuepress-----22、其他評論方案

vuepress 支持評論 本文講述 vuepress 站點如何集成評論系統&#xff0c;選型是 valineleancloud, 支持匿名評論&#xff0c;缺點是數據沒有存儲在自己手里。市面上也有其他的方案, 如 gitalk,vssue 等, 但需要用戶登錄 github 才能發表評論, 但 github 經常無法連接,導致體驗…

[wp]“古劍山”第一屆全國大學生網絡攻防大賽 Web部分wp

“古劍山”第一屆全國大學生網絡攻防大賽 群友說是原題杯 哈哈哈哈 我也不懂 我比賽打的少 Web Web | unse 源碼&#xff1a; <?phpinclude("./test.php");if(isset($_GET[fun])){if(justafun($_GET[fun])){include($_GET[fun]);}}else{unserialize($_GET[…

使用cmake構建的工程的編譯方法

1、克隆項目工程 2、進入到工程目錄 3、執行 mkdir build && cd build 4、執行 cmake .. 5、執行 make 執行以上步驟即可完成對cmake編寫的工程進行編譯 &#xff0c;后面只需執行你的編譯結果即可 $ git clone 你想要克隆的代碼路徑 $ cd 代碼文件夾 $ mkdir bu…

測試:SRE

SRE&#xff08;Site Reliability Engineering&#xff0c;站點可靠性工程&#xff09;是一種關注于構建、運行和維護大規模分布式系統的工程學科。它旨在確保系統在各種故障情況下仍然可用、可靠和高效。 SRE的核心目標是通過軟件工程的方法來解決系統可靠性問題&#xff0c;…

WPF DataGrid 里面的ToggleButton點擊不生效

已解決&#xff1a;根本原因是沒寫UpdateSourceTriggerPropertyChanged <ToggleButton IsChecked"{Binding PathIsEnabled,ModeTwoWay,UpdateSourceTriggerPropertyChanged}"/> 具體原因參考下面文章&#xff1a;鳴謝作者 WPF 數據集合綁定到DataGrid、ListV…

vmware安裝centos7總結

vmware安裝centos7總結 文章目錄 vmware安裝centos7總結一、配置網絡&#xff08;橋接模式&#xff09;二、配置yum源&#xff08;連網配置&#xff09;三、可視化界面四、安裝Docker五、安裝DockerUI 一、配置網絡&#xff08;橋接模式&#xff09; 網絡連接模式選擇橋接模式…

Ubuntu安裝nvidia GPU顯卡驅動教程

Ubuntu安裝nvidia顯卡驅動 1.安裝前安裝必要的依賴 sudo apt-get install build-essential sudo apt-get install g sudo apt-get install make2.到官網下載對應驅動 https://www.nvidia.cn/Download/index.aspx?langcn 3.卸載原有驅動 sudo apt-get remove --purge nvidi…

深度學習:注意力機制(Attention Mechanism)

1 注意力機制概述 1.1 定義 注意力機制&#xff08;Attention Mechanism&#xff09;是深度學習領域中的一種重要技術&#xff0c;特別是在序列模型如自然語言處理&#xff08;NLP&#xff09;和計算機視覺中。它使模型能夠聚焦于輸入數據的重要部分&#xff0c;從而提高整體…

孩子都能學會的FPGA:第二十五課——用FPGA實現頻率計

&#xff08;原創聲明&#xff1a;該文是作者的原創&#xff0c;面向對象是FPGA入門者&#xff0c;后續會有進階的高級教程。宗旨是讓每個想做FPGA的人輕松入門&#xff0c;作者不光讓大家知其然&#xff0c;還要讓大家知其所以然&#xff01;每個工程作者都搭建了全自動化的仿…

基于SpringBoot+maven+Mybatis+html慢性病報銷系統(源碼+數據庫)

一、項目簡介 本項目是一套基于SpringBootmavenMybatishtml慢性病報銷系統&#xff0c;主要針對計算機相關專業的正在做bishe的學生和需要項目實戰練習的Java學習者。 包含&#xff1a;項目源碼、數據庫腳本等&#xff0c;該項目可以直接作為bishe使用。 項目都經過嚴格調試&a…

二十一章(網絡通信)

計算機網絡實現了多臺計算機間的互聯&#xff0c;使得它們彼此之間能夠進行數據交流。網絡應用程序就是在已連接的不同計算機上運行的程序&#xff0c;這些程序借助于網絡協議&#xff0c;相互之間可以交換數據。編寫網絡應用程序前&#xff0c;首先必須明確所要使用的網絡協議…

C++_命名空間(namespace)

目錄 1、namespace的重要性 2、 namespace的定義及作用 2.1 作用域限定符 3、命名空間域與全局域的關系 4、命名空間的嵌套 5、展開命名空間的方法 5.1 特定展開 5.1 部分展開 5.2 全部展開 結語&#xff1a; 前言&#xff1a; C作為c語言的“升級版”&#xff0c;其在…

快速排序的新用法

普通快排 簡介 快速排序是一種高效的排序算法&#xff0c;利用分治的思想進行排序。它的基本原理是在待排序的n個數據中任取一個數據為分區標準&#xff0c;把所有小于該排序碼的數據移到左邊&#xff0c;把所有大于該排序碼的數據移到右邊&#xff0c;中間放所選記錄&#x…

Spring 之 @Cacheable 緩存使用教程

1、Cacheable 指定使用緩存 定義個 Controller &#xff0c;在方法上加上注解 Cacheable&#xff0c;配置要使用哪些緩存&#xff0c;比如 myMapCache 表示一級緩存是 Map&#xff0c;myRedisCache 表示二級緩存是 Redis。并配置緩存 key。 key 由 SPEL 表達式組成&#xff0c…

異常檢測 | MATLAB實現BiLSTM(雙向長短期記憶神經網絡)數據異常檢測

異常檢測 | MATLAB實現BiLSTM(雙向長短期記憶神經網絡)數據異常檢測 目錄 異常檢測 | MATLAB實現BiLSTM(雙向長短期記憶神經網絡)數據異常檢測效果一覽基本介紹模型準備模型設計參考資料效果一覽 基本介紹 訓練一個雙向 LSTM 自動編碼器來檢測機器是否正常工作。 自動編碼器接受…