【數據結構】(C語言):動態數組

動態數組:

  • 內存區域連續,即每個元素的內存地址連續。
  • 可用索引查看元素,數組[索引號]。
  • 指定位置刪除元素,該位置之后的元素全部往前移動一位。
  • 指定位置添加元素,從最后到該位置的元素全部往后移動一位。
  • 物理大小:創建數組時,指定的容量大小。邏輯大小:實際已使用的容量大小。
  • 擴容:數組滿時,擴大數組的內存空間。(方法:開辟新的內存空間,將原數組內容復制到新的內存區域。)
  • 縮容:數組使用容量遠小于數組物理大小時,縮小數組的內存空間。(方法:開辟新的內存空間,將原數組內容復制到新的內存區域。)


C語言實現:

創建結構體數據類型:

typedef struct Array
{int *p;			// 數組地址,即連續內存地址的首地址int length;		// 數組物理大小,即最大容納多少元素int n;			// 數組邏輯大小,即實際存儲多少元素
}Array;        	    // 別名

創建數組變量:?

Array array;

初始化數組:

void init(Array *arr, int len)
{arr->p = (int *)malloc(len * sizeof(int));    // 分配數組內存空間if(arr->p == NULL){perror("Memory allocation failed");exit(-1);}arr->length = len;                            // 指定數組物理大小arr->n = 0;                                   // 邏輯大小初始化為0
}

擴容、縮容:

使用realloc動態分配內存空間,若分配新內存,會將內容復制到新地址。

void resize(Array *arr, int len)
{int *t = (int *)realloc(arr->p, len * sizeof(int));// for(int k = 0; k < arr->n; k++)// {// 	t[k] = arr->p[k];// }arr->p = t;arr->length = len;
}

添加元素:

若數組滿,擴容(本文為內存空間擴大一倍)。

// 在數組尾部添加
void append(Array *arr, int data)
{if(arr->length == arr->n)		// 若數組滿,擴容一倍{int newlength = arr->length * 2;	resize(arr, newlength);}arr->p[arr->n] = data;arr->n++;                    // 每添加一個元素,邏輯大小+1
}
// 在數組指定位置添加元素
void insert(Array *arr, int i, int data)
{if(arr->length == arr->n)		// 數組滿,擴容一倍{int newlength = arr->length * 2;resize(arr, newlength);}if(i < 0 || i > arr->n)         // 檢查索引號是否越界{perror("index out of bounds");return ;}// 從最后一個元素到指定位置元素都要往后移動一位,空出位置給新元素int k;for(k = arr->n - 1; k >= i; k--){arr->p[k+1] = arr->p[k];}arr->p[k + 1] = data;arr->n++;
}

刪除元素:

若數組實際存儲數據小于物理大小的一半,縮容(本文將內存空間縮小一半但不小于4)。

// 從數組尾部刪除元素
int pop(Array *arr)
{if(arr->n == 0) return -1;int value = arr->p[arr->n - 1];arr->n--;                         // 每刪除一個元素,邏輯大小-1// 若實際數據<物理大小一半,縮容,但物理大小不小于4	if(arr->n < ceil(arr->length / 2) && arr->length > 4){int newlength = ceil(arr->length / 2);resize(arr, newlength);}return value;
}
// 在數組指定位置刪除元素
int del(Array *arr, int i)
{if(i < 0 || i > arr->n || arr->n == 0)   // 檢查索引號是否越界{perror("index out of bounds");exit(-1);}int value = arr->p[i];		// 從指定位置到最后的元素都要往前移動一位for(int k = i; k < arr->n; k++){arr->p[i] = arr->p[i+1];}arr->n--;if(arr->n < ceil(arr->length / 2) && arr->length > 4)   //  達到條件,縮容{int newlength = ceil(arr->length / 2);resize(arr, newlength);}return value;
}

遍歷數組元素,獲取指定位置元素:

// 遍歷數組元素
void travel(Array *arr)
{if(arr->n == 0) return ;printf("elements: ");for(int k = 0; k < arr->n; k++){printf("%d  ", arr->p[k]);}printf("\n");
}
// 獲取指定位置元素
int get(Array *arr, int i)
{if(i < 0 || i > arr->n || arr->n == 0)    // 檢查索引號是否越界{perror("index out of bounds");exit(-1);}return arr->p[i];
}

排序(從小到大),倒置(從最后到開頭):

// 排序(從小到大,冒泡排序,還有其他排序方法此處省略)
void sort(Array *arr)
{int x = 0;for(int k = arr->n-1; k > 0; k--){for(int i = 0; i < k; i++){if(arr->p[i] > arr->p[i+1]){int tmp = arr->p[i];arr->p[i] = arr->p[i+1];arr->p[i+1] = tmp;x = 1;}}if(x == 0) break;}
}
// 倒置(從最后到開頭)
void inverse(Array *arr)
{if(arr->n == 0) return;for(int i = 0, k = arr->n-1; i < k; i++, k--){int tmp = arr->p[i];arr->p[i] = arr->p[k];arr->p[k] = tmp;}
}


完整代碼:(array.c)

#include <stdio.h>
#include <stdlib.h>
#include <math.h>/* structure */
typedef struct Array		// array structure
{int *p;			// array memory addressint length;		// maximum number of arrayint n;			// actual number of array
}Array;/* function prototype */
void init(Array *, int);		// array initialization
void resize(Array *, int);		// increase or reduce the size of the array
void append(Array *, int);		// add element to the end of the array
void insert(Array *, int, int);		// add element to the specify location(start with 0)
void travel(Array *);			// show element one by one
int pop(Array *);			// delete element from the end of the array
int del(Array *, int);			// delete element from the specify location of the array
int get(Array *, int);			// show element at the specify location(start with 0)
void sort(Array *);			// sort array from small to large
void inverse(Array *);			// sort array form end to start/* main function */
int main(void)
{Array array;init(&array, 4);printf("lenght is %d, actual is %d\n", array.length, array.n);append(&array, 2);append(&array, 9);printf("lenght is %d, actual is %d\n", array.length, array.n);travel(&array);insert(&array, 1, 12);insert(&array, 0, 25);printf("lenght is %d, actual is %d\n", array.length, array.n);travel(&array);get(&array, 2);		// get element that index=2(start with 0)sort(&array);		// sort from small to largetravel(&array);inverse(&array);	// sort from end to starttravel(&array);append(&array, 66);	// actual length > length,need increase the size of the arrayprintf("lenght is %d, actual is %d\n", array.length, array.n);travel(&array);del(&array, 3);printf("lenght is %d, actual is %d\n", array.length, array.n);travel(&array);pop(&array);		// actual length < length/2,need reduce the size of the arrayprintf("lenght is %d, actual is %d\n", array.length, array.n);travel(&array);pop(&array);pop(&array);pop(&array);printf("lenght is %d, actual is %d\n", array.length, array.n);travel(&array);return 0;
}/* subfunction */
void init(Array *arr, int len)		// array initialization
{arr->p = (int *)malloc(len * sizeof(int));if(arr->p == NULL){perror("Memory allocation failed");exit(-1);}arr->length = len;arr->n = 0;
}void resize(Array *arr, int len)		// increase or reduce the size of the array
{int *t = (int *)realloc(arr->p, len * sizeof(int));//for(int k = 0; k < arr->n; k++)//{//	t[k]= arr->p[k];//}arr->p = t;arr->length = len;	
}void append(Array *arr, int data)		// add element to the end of the array
{if(arr->length == arr->n)		// if array is full, expand the array to double size{int newlength = arr->length * 2;	resize(arr, newlength);}arr->p[arr->n] = data;arr->n++;
}void insert(Array *arr, int i, int data)	// add element to the specify location(start with 0)
{if(arr->length == arr->n)		// if array is full, expand the array to double size{int newlength = arr->length * 2;resize(arr, newlength);}if(i < 0 || i > arr->n){perror("index out of bounds");return ;}int k;for(k = arr->n - 1; k >= i; k--)	// from end to i,each element move back a place{arr->p[k+1] = arr->p[k];}arr->p[k + 1] = data;			// leave an empty slot for the new elementarr->n++;
}void travel(Array *arr)			// show element one by one
{if(arr->n == 0) return ;printf("elements: ");for(int k = 0; k < arr->n; k++){printf("%d  ", arr->p[k]);}printf("\n");
}int pop(Array *arr)			// delete element from the end of the array
{if(arr->n == 0) return -1;int value = arr->p[arr->n - 1];arr->n--;if(arr->n < ceil(arr->length / 2) && arr->length > 4)   //  reduce the size of array{int newlength = ceil(arr->length / 2);resize(arr, newlength);}return value;
}int del(Array *arr, int i)		// delete element from the specify location of the array
{if(i < 0 || i > arr->n || arr->n == 0){perror("index out of bounds");exit(-1);}int value = arr->p[i];		// from i to end,each element move forward one placefor(int k = i; k < arr->n; k++){arr->p[i] = arr->p[i+1];}arr->n--;if(arr->n < ceil(arr->length / 2) && arr->length > 4)   //  reduce the size of array{int newlength = ceil(arr->length / 2);resize(arr, newlength);}return value;
}int get(Array *arr, int i)		// show element at the specify location(start with 0)
{if(i < 0 || i > arr->n || arr->n == 0){perror("index out of bounds");exit(-1);}return arr->p[i];
}void sort(Array *arr)			// sort array from small to large
{int x = 0;for(int k = arr->n-1; k > 0; k--){for(int i = 0; i < k; i++){if(arr->p[i] > arr->p[i+1]){int tmp = arr->p[i];arr->p[i] = arr->p[i+1];arr->p[i+1] = tmp;x = 1;}}if(x == 0) break;}
}void inverse(Array *arr)		// sort array form end to start
{if(arr->n == 0) return;for(int i = 0, k = arr->n-1; i < k; i++, k--){int tmp = arr->p[i];arr->p[i] = arr->p[k];arr->p[k] = tmp;}
}

編譯鏈接: gcc -o array array.c

執行可執行文件:?./array

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

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

相關文章

【保姆級講解ECMAScript和JavaScript之間的區別】

&#x1f3a5;博主&#xff1a;程序員不想YY啊 &#x1f4ab;CSDN優質創作者&#xff0c;CSDN實力新星&#xff0c;CSDN博客專家 &#x1f917;點贊&#x1f388;收藏?再看&#x1f4ab;養成習慣 ?希望本文對您有所裨益&#xff0c;如有不足之處&#xff0c;歡迎在評論區提出…

mysql 升級到8.0

MySQL :: MySQL 8.0 Reference Manual :: 3.7 Upgrading MySQL Binary or Package-based Installations on Unix/Linux 2種升級方式&#xff1a; In-Place Upgrade &#xff1a; data目錄替換 Logical Upgrade&#xff1a; 通過 mysqldump 導出為sql文本后&#xff0c;導入…

全面國產化信創適配改造方案說明

一、概敘 系統的全面國產化適配改造需要從多個方面進行考慮&#xff0c;改造前需要進行充分的論證&#xff0c;在滿足具體業務場景的前提下&#xff0c;以確保系統的穩定性和安全性&#xff0c;同時還要考慮技術的發展&#xff0c;不斷優化和更新。因此全面國產化適配改造也面臨…

Redis集群安裝(三主三從一哨兵)

Redis集群安裝&#xff08;三主三從一哨兵&#xff09; 一&#xff0c;搭建環境 ? 在三臺服務器上分別搭建redis并測試是否能啟動&#xff08;搭建方法&#xff09; 二&#xff0c;Redis cluster三主三從 配置環境變量 vim /etc/profile #添加如下內容 export REDIS_HOME…

AI 開發平臺(Coze)搭建《AI女友(多功能版本)》

前言 本文講解如何從零開始&#xff0c;使用扣子平臺去搭建《AI女友&#xff08;多功能版本&#xff09;》 bot直達&#xff1a;AI女友&#xff08;多功能版&#xff09; - 扣子 AI Bot (coze.cn) 歡迎大家前去體驗&#xff01;&#xff01;&#xff01; 正文 功能介紹 …

系統架構師考點--系統配置與性能評價

大家好。今天我們來總結一下系統配置與性能評價的考點內容&#xff0c;這一部分一般是出在上午場的選擇題中&#xff0c;占1-2分左右。 一、性能指標 計算機 對計算機評價的主要性能指標有&#xff1a;時鐘頻率(主頻)&#xff1b;運算速度&#xff1b;運算精度內存的存儲容量…

ManageEngine連續榮登Gartner 2024年安全信息和事件管理魔力象限

我們很高興地宣布&#xff0c;ManageEngine再次在Gartner的安全信息和事件管理&#xff08;SIEM&#xff09;魔力象限中榜上有名&#xff0c;這是我們連續第七年獲得這一認可。 Gartner ManageEngine Log360是一款全面的SIEM解決方案&#xff0c;旨在幫助組織有效處理日志數據…

計算機共形幾何簡介

計算機共形幾何&#xff08;Computational Conformal Geometry&#xff09;是一門研究計算機圖形學和幾何學結合的領域&#xff0c;主要研究曲面的表示、形變和分析等問題。共形幾何是研究保持角度度量不變的幾何變換&#xff0c;而計算機共形幾何則是將共形幾何的概念和方法應…

cuda 學習筆記4

一 基本函數 在GPU上開辟空間&#xff0c;無論定義的數據是float還是int ,還是****gpu_int,分配空間的函數都是下面固定的形式 (void**)& 1.函數定義&#xff0c;global void 是配套使用的&#xff0c;是在GPU上定義&#xff0c;也就是GPU上執行&#xff0c;CPU上調用的函數…

python pyautogui.position實時輸出坐標

import pyautogui import timewhile True:# 獲取鼠標當前坐標x, y pyautogui.position()# 打印坐標print(f"當前坐標&#xff1a;({x}, {y})")# 暫停1秒time.sleep(1) 輸出實時鼠標位置坐標

Java高手的30k之路|面試寶典|精通MySQL(二)

分區表 分區類型 MySQL 支持以下幾種表分區類型&#xff0c;這些分區類型有助于優化大型表的管理和查詢性能&#xff1a; Range Partitioning&#xff08;范圍分區&#xff09;&#xff1a; 范圍分區是基于列的值范圍來分配數據的。你可以定義一個或多個列的值區間&#xff0…

62.指針和二維數組(2)

一.指針和二維數組 1.如a是一個二維數組&#xff0c;則數組中的第i行可以看作是一個一維數組&#xff0c;這個一維數組的數組名是a[i]。 2.a[i]代表二維數組中第i行的首個元素的地址&#xff0c;即a[i][0]的地址。 二.進一步思考 二維數組可以看作是數組的數組&#xff0c;本…

springboot+vue+mybatis母嬰二手銷售系統+PPT+論文+講解+售后

目前由于我國二手銷售的規模較小,同發達國家相比,二手銷售比重始終偏低,消費總額增長緩慢,進一步抑制了市場消費的提升,隨著市場競爭的日益激烈,雖然許多商家主動選用二手銷售模式,但卻缺乏對其充分的重視與銷售風險的良性控制,一些商家沒有建立獨立的信用實踐管理部門,無法在交…

linux使用docker部署kafka集群

1、拉取kafka docker pull wurstmeister/kafka docker pull wurstmeister/zookeeper 2、創建網絡 docker network create app-kafka 3、啟動zookeeper docker run -d \--name zookeeper \-p 2181:2181 \--network app-kafka \--restart always \wurstmeister/zookeeper …

【ISAC】通感一體化講座(劉凡)

高斯信道下通信感知一體化的性能極限(劉凡) 文章目錄 背景背景 通信和感知在硬件結構上相似,高效地利用資源,實現相互的增益; 感知是基于不同的任務,比如目標檢測(檢測概率,虛警概率),估計任務(從收到的信號中去估計有用的參數,均方誤差,CRB),識別(知道目標的…

Str.format()方法

自學python如何成為大佬(目錄):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 語法參考 在Python2.6之后&#xff0c;提供了字符串的format()方法對字符串進行格式化操作。format()功能非常強大&#xff0c;格式也比較復雜&…

基于ADRC自抗擾算法的UAV飛行姿態控制系統simulink建模與仿真

目錄 1.課題概述 2.系統仿真結果 3.核心程序與模型 4.系統原理簡介 4.1 控制系統概述 4.2 ADRC基本框架 4.3 控制律設計 5.完整工程文件 1.課題概述 基于ADRC自抗擾算法的UAV飛行姿態控制系統simulink建模與仿真&#xff0c;分別對YAW&#xff0c;PITCH&#xff0c;ROL…

K-Means 算法詳解

K-Means 是一種常用的無監督學習算法&#xff0c;廣泛應用于數據聚類分析。本文將詳細講解 K-Means 算法的原理、步驟、公式以及 Python 實現&#xff0c;幫助你深入理解這一經典算法。 什么是 K-Means 算法&#xff1f; K-Means 算法是一種基于原型的聚類算法&#xff0c;其…

Linux分區以及磁盤管理

目錄 一、磁盤 1.磁盤結構 1.1物理結構 1.2數據結構 2.1磁盤容量 2.2磁盤接口類型 2.磁盤分區的表示 3.MBR與磁盤分區表示 4.磁盤分區結構 二、文件系統 1、類型 三、命令 1.檢測并確認新硬盤 2.創建系統文件(格式化) 2.1mkfs命令 2.2SWAP 3.掛載、卸載文件系統…

Simulink中三相PMSM配置及使用

1. 模塊介紹 Simulink提供了專門用于電力系統仿真&#xff0c;包括電機的動態建模和控制的電機模型&#xff0c;其中&#xff0c;永磁同步電機模塊 Permanent Magnet Synchronous Machine 支持實現三相或五相永磁同步電機模擬&#xff0c;電機繞組采用星型連接&#xff0c;在這…