C語言相關簡單數據結構:順序表

目錄

1.順序表的概念及結構

1.1 線性表

如何理解邏輯結構和物理結構?

1.2 順序表分類

順序表和數組的區別:

順序表分類:

靜態順序表

動態順序表

1.3 動態順序表的實現

初始化

尾插

頭插

尾刪

頭刪

在指定位置之前插入數據

刪除指定位置的數據

順序表的查找

最終代碼:

test.c

SeqList.h

SeqList.c

2.順序表實現通訊錄

2.1?基于動態順序表實現通訊錄

2.1.1 功能要求

2.2 代碼的實現:

1.建立五個文件

2.將順序表結構體的類型,int改為通訊錄結構體自定義類型

順序表

通訊錄

3.給通訊錄結構體改名為typedef SL contact

4.對于SeqList.h和Contact.h頭文件包含的處理

5.列出通訊錄的功能

6.通訊錄的初始化和銷毀

7.通訊錄的添加數據

8.通訊錄刪除

9.展示通訊錄數據

10.通訊錄的修改和查找

11.打印菜單

最終代碼

test.c

Contact.h

Contact.c


1.順序表的概念及結構

1.1 線性表

線性表(linear list)是n個具有相同特性的數據元素的有限序列。線性表是?種在實際中?泛使?的數據結構,常?的線性表:順序表、鏈表、棧、隊列、字符串...線性表在邏輯上是線性結構,也就說是連續的?條直線。但是在物理結構上并不?定是連續的,線性表在物理上存儲時,通常以數組和鏈式結構的形式存儲。案例:蔬菜分為綠葉類、?類、菌菇類。線性表指的是具有部分相同特性的?類數據結構的集合

如何理解邏輯結構和物理結構?

物理結構:在內存中存儲的形式,不一定連續

邏輯結構:肉眼可以看到的,我們想象出來的數據結構,人為想象的,連續的

順序表是物理結構和邏輯結構都連續的一種線性表

1.2 順序表分類

順序表和數組的區別:

順序表的底層結構是數組,對數組的封裝,實現了常?的增刪改查等接?

順序表分類:

靜態順序表

概念:使?定?數組存儲元素

靜態順序表缺陷:空間給少了不夠?,給多了造成空間浪費

動態順序表

1.3 動態順序表的實現

初始化

尾插

頭插

尾刪

頭刪

在指定位置之前插入數據

刪除指定位置的數據

順序表的查找

最終代碼:

test.c
#include"SeqList.h"void SLTest01()
{SL sl;SLInit(&sl);SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);SLPrint(sl);//1 2 3 4//SLPushFront(&sl, 5);//SLPushFront(&sl, 6);SLPopBack(&sl);SLPrint(sl);//1 2 3 SLPopBack(&sl);SLPrint(sl);SLPopBack(&sl);SLPrint(sl);SLPopBack(&sl);SLPrint(sl);SLPopFront(&sl);SLPrint(sl);//...........SLDestroy(&sl);
}void SLTest02()
{SL sl;SLInit(&sl);SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);SLPrint(sl);//1 2 3 4//測試指定位置之前插入數據//SLInsert(&sl, 1, 99);//SLInsert(&sl, sl.size, 88);//測試刪除指定位置的數據//SLErase(&sl, 1);//SLPrint(sl);//1 3  4//測試順序表的查找int find = SLFind(&sl, 40);if (find < 0){printf("沒有找到!\n");}else {printf("找到了!下標為%d\n",find);}SLDestroy(&sl);
}int main()
{SLTest01();SLTest02();return 0;
}
SeqList.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//定義順序表的結構//#define N 100
//
////靜態順序表
//struct SeqList
//{
//	int arr[N];
//	int size;//有效數據個數
//};typedef int SLDataType;
//動態順序表
typedef struct SeqList
{SLDataType* arr;int size; //有效數據個數int capacity; //空間大小
}SL;//typedef struct SeqList SL;//順序表初始化
void SLInit(SL* ps);
//順序表的銷毀
void SLDestroy(SL* ps);
void SLPrint(SL s);//頭部插入刪除 / 尾部插入刪除
void SLPushBack(SL* ps, SLDataType x);//尾插
void SLPushFront(SL* ps, SLDataType x);//頭插void SLPopBack(SL* ps);//尾刪
void SLPopFront(SL* ps);//頭刪//指定位置之前插入/刪除數據
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);
int SLFind(SL* ps, SLDataType x);
SeqList.c
#include"SeqList.h"
void SLInit(SL* ps)
{ps->arr = NULL;ps->size = ps->capacity = 0;
}
//順序表的銷毀
void SLDestroy(SL* ps)
{if (ps->arr) //等價于  if(ps->arr != NULL){free(ps->arr);}ps->arr = NULL;ps->size = ps->capacity = 0;
}
void SLCheckCapacity(SL* ps)
{//插入數據之前先看空間夠不夠if (ps->capacity == ps->size){//申請空間//malloc calloc realloc  int arr[100] --->增容realloc//三目表達式int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;SLDataType* tmp = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));//要申請多大的空間if (tmp == NULL){perror("realloc fail!");exit(1);//直接退出程序,不再繼續執行}//空間申請成功ps->arr = tmp;ps->capacity = newCapacity;}
}
//尾插
void SLPushBack(SL* ps, SLDataType x)
{////溫柔的解決方式//if (ps == NULL)//{//	return;//}assert(ps); //等價與assert(ps != NULL)//ps->arr[ps->size] = x;//++ps->size;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];//arr[1] = arr[0]}ps->arr[0] = x;ps->size++;
}void SLPrint(SL s)
{for (int i = 0; i < s.size; i++){printf("%d ", s.arr[i]);}printf("\n");
}
void SLPopBack(SL* ps)
{assert(ps);assert(ps->size);//順序表不為空//ps->arr[ps->size - 1] = -1;--ps->size;
}
void SLPopFront(SL* ps)
{assert(ps);assert(ps->size);//數據整體往前挪動一位for (int i = 0; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1]; //arr[size-2] = arr[size-1]}ps->size--;
}//在指定位置之前插入數據
// 1 2   size = 2
//pos 0 -1 100000
void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);//插入數據:空間夠不夠SLCheckCapacity(ps);//讓pos及之后的數據整體往后挪動一位for (int i = ps->size; i > pos; i--){ps->arr[i] = ps->arr[i - 1];//arr[pos+1] = arr[pos]}ps->arr[pos] = x;ps->size++;
}
//刪除指定位置的數據
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);for (int i = pos; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}
//查找
int SLFind(SL* ps, SLDataType x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->arr[i] == x){//找到啦return i;}}//沒有找到return -1;
}

2.順序表實現通訊錄

2.1?基于動態順序表實現通訊錄

C語?基礎要求:結構體、動態內存管理、順序表、?件操作

2.1.1 功能要求

1)?少能夠存儲100個?的通訊信息

2)能夠保存??信息:名字、性別、年齡、電話、地址等

3)增加聯系?信息

4)刪除指定聯系?

5)查找制定聯系?

6)修改指定聯系?

7)顯?聯系?信息

2.2 代碼的實現:

1.建立五個文件

分別為SeqList.c和SeqList.h,這兩個是通訊錄的底層文件;Contact.c和Contact.h,這兩個函數是通訊錄的實現文件;test.c是測試函數

2.將順序表結構體的類型,int改為通訊錄結構體自定義類型

順序表

SeqList.h

通訊錄

Contact.h

3.給通訊錄結構體改名為typedef SL contact

4.對于SeqList.h和Contact.h頭文件包含的處理

因為SeqList.h中包含了Contact.h所以可以直接使用重命名peoInfo

因為Contact.h沒有包含SeaList.h所以找不到順序表的結構體,但是SeqList.h已經包含了Contact.h不能相互包含頭文件,會報錯,所以要在Contact.h前置聲明struct SeqList;所以typedef struct SeqList Contact;這樣才能找到SL

由以上兩步通訊錄的實現和順序表有了連接

5.列出通訊錄的功能

6.通訊錄的初始化和銷毀

在Contact.c包含頭文件SeqList.h

通訊錄的初始化和銷毀就是順序表的初始化和銷毀

測試,通過調試觀察

7.通訊錄的添加數據

將姓名、性別、年齡、電話號碼、地址儲存進通訊錄的結構體,注意:只要年齡是int類型的,所以要&,其他的都是數組,數組名表示首元素地址;然后調用頭插/尾插函數(自定義都能實現)

測試,通過調試觀察

8.通訊錄刪除

通訊錄的刪除就是順序表的刪除,調用順序表的刪除函數,調用指定刪除函數,不是頭刪也不是尾刪

測試,通過調試觀察

9.展示通訊錄數據

測試,直接打印

10.通訊錄的修改和查找

測試,直接打印

11.打印菜單

最終代碼

test.c
#include"SeqList.h"void menu()
{printf("******************通訊錄******************\n");printf("*******1.增加聯系人   2.刪除聯系人********\n");printf("*******3.修改聯系人   4.查找聯系人********\n");printf("*******5.展示聯系人   0.   退出  *********\n");printf("******************************************\n");
}int main()
{int op = -1;Contact con;ContactInit(&con);do {menu();printf("請選擇您的操作:\n");scanf("%d", &op);//要根據對應的op執行不同的操作switch (op){case 1:ContactAdd(&con);break;case 2:ContactDel(&con);break;case 3:ContactModify(&con);break;case 4:ContactFind(&con);break;case 5:ContactShow(&con);break;case 0:printf("退出通訊錄....\n");break;default:printf("輸入錯誤,請重新選擇您的操作!\n");break;}} while (op != 0);ContactDesTroy(&con);return 0;
}
Contact.h
#pragma once
#define NAME_MAX 20
#define GENDER_MAX 10 
#define TEL_MAX 20
#define ADDR_MAX 100
//定義聯系人數據 結構
//姓名 性別 年齡 電話 地址
typedef struct personInfo
{char name[NAME_MAX];char gender[GENDER_MAX];int age;char tel[TEL_MAX];char addr[ADDR_MAX];
}peoInfo;//要用到順序表相關的方法,對通訊錄的操作實際就是對順序表進行操作
//給順序表改個名字,叫做通訊錄
typedef struct SeqList Contact; //sl
//通訊錄相關的方法//通訊錄的初始化
void ContactInit(Contact* con);
//通訊錄的銷毀
void ContactDesTroy(Contact* con);
//通訊錄添加數據
void ContactAdd(Contact* con);
//通訊錄刪除數據
void ContactDel(Contact* con);
//通訊錄的修改
void ContactModify(Contact* con);
//通訊錄查找
void ContactFind(Contact* con);
//展示通訊錄數據
void ContactShow(Contact* con);
Contact.c
#include"Contact.h"
#include"SeqList.h"//通訊錄的初始化
void ContactInit(Contact* con)//sl
{//實際上要進行的是順序表的初始化//順序表的初始化已經實現好了SLInit(con);
}
//通訊錄的銷毀
void ContactDesTroy(Contact* con)
{SLDestroy(con);
}
//通訊錄添加數據
void ContactAdd(Contact* con)
{//獲取用戶輸入的內容:姓名+性別+年齡+電話+地址peoInfo info;printf("請輸入要添加的聯系人姓名:\n");scanf("%s", info.name);printf("請輸入要添加的聯系人性別:\n");scanf("%s", info.gender);printf("請輸入要添加的聯系人年齡:\n");scanf("%d", &info.age);printf("請輸入要添加的聯系人電話:\n");scanf("%s", info.tel);printf("請輸入要添加的聯系人住址:\n");scanf("%s", info.addr);//往通訊錄中添加聯系人數據SLPushBack(con, info);
}int FindByName(Contact* con, char name[])
{for (int i = 0; i < con->size; i++){if (0 == strcmp(con->arr[i].name, name)){//找到了return i;}}//沒有找到return -1;
}//通訊錄刪除數據
void ContactDel(Contact* con)
{//要刪除的數據必須要存在,才能執行刪除操作//查找char name[NAME_MAX];printf("請輸入要刪除的聯系人姓名:\n");scanf("%s", name);int find = FindByName(con, name);if (find < 0){printf("要刪除的聯系人數據不存在!\n");return;}//要刪除的聯系人數據存在--->知道了要刪除的聯系人數據對應的下標SLErase(con, find);printf("刪除成功!\n");
}
//展示通訊錄數據
void ContactShow(Contact* con)
{//表頭:姓名  性別 年齡 電話  地址printf("%s %s %s %s %s\n", "姓名", "性別", "年齡", "電話", "地址");//遍歷通訊錄,按照格式打印每個聯系人數據for (int i = 0; i < con->size; i++){printf("%3s %3s %3d %3s %3s\n", //手動調整一下格式con->arr[i].name,con->arr[i].gender,con->arr[i].age,con->arr[i].tel,con->arr[i].addr);}
}
//通訊錄的修改
void ContactModify(Contact* con)
{//要修改的聯系人數據存在char name[NAME_MAX];printf("請輸入要修改的用戶姓名:\n");scanf("%s", name);int find = FindByName(con, name);if (find < 0){printf("要修改的聯系人數據不存在!\n");return;}//直接修改printf("請輸入新的姓名:\n");scanf("%s", con->arr[find].name);printf("請輸入新的性別:\n");scanf("%s", con->arr[find].gender);printf("請輸入新的年齡:\n");scanf("%d", &con->arr[find].age);printf("請輸入新的電話:\n");scanf("%s", con->arr[find].tel);printf("請輸入新的住址:\n");scanf("%s", con->arr[find].addr);printf("修改成功!\n");
}
//通訊錄查找
void ContactFind(Contact* con)
{//11char name[NAME_MAX];printf("請輸入要查找的聯系人姓名\n");scanf("%s", name);int find = FindByName(con, name);if (find < 0){printf("要查找的聯系人數據不存在!\n");return;}// 姓名 性別 年齡 電話  地址// 11   11   11   11   11printf("%s %s %s %s %s\n", "姓名", "性別", "年齡", "電話", "地址");printf("%3s %3s %3d %3s %3s\n", //手動調整一下格式con->arr[find].name,con->arr[find].gender,con->arr[find].age,con->arr[find].tel,con->arr[find].addr);
}

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

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

相關文章

nginx配置代理服務器

Nginx 作為代理服務器時&#xff0c;主要用于反向代理&#xff08;最常用&#xff0c;轉發客戶端請求到后端服務&#xff09;或正向代理&#xff08;較少用&#xff0c;為客戶端提供訪問外部網絡的代理&#xff09;。以下是兩種場景的具體配置示例&#xff1a; 一、反向代理配置…

MySQL數據庫知識體系總結 20250813

一、數據庫的原理 1.數據庫的分類 我們可以根據數據的結構類型&#xff0c;將數據分成三類&#xff0c;分別是&#xff1a;結構化數據&#xff0c;半結構化數據&#xff0c;非結構化數據。 要點&#xff1a;對于結構化數據來講通常是先有結構再有數據。要點&#xff1a;對于半…

C++ 中構造函數參數對父對象的影響:父子控件管理機制解析

文章目錄C 中構造函數參數對父對象的影響&#xff1a;父子控件管理機制解析1. Qt 中的父對象管理機制2. 構造函數傳遞父對象的不同方式2.1. 父控件是 QWidget parent&#xff08;通用方式&#xff09;分析&#xff1a;2.2. 父控件是 Books_Client parent&#xff08;限制父控件…

直播美顏SDK開發實戰:高性能人臉美型的架構與實現

在直播行業里&#xff0c;美顏已經不再是錦上添花&#xff0c;而是標配中的標配。無論是游戲主播、帶貨達人&#xff0c;還是唱歌、跳舞的才藝主播&#xff0c;直播美顏SDK往往決定了用戶的第一印象和停留時長。尤其是高性能人臉美型技術&#xff0c;不僅能讓主播的五官更加自然…

JavaWeb(蒼穹外賣)--學習筆記18(Apache POI)

前言 本篇文章是學習B站黑馬程序員蒼穹外賣的學習筆記&#x1f4d1;。我的學習路線是Java基礎語法-JavaWeb-做項目&#xff0c;管理端的功能學習完之后&#xff0c;就進入到了用戶端微信小程序的開發&#xff0c;用戶端開發的流程大致為用戶登錄—商品瀏覽&#xff08;其中涉及…

OpenJDK 17 源碼 安全點輪詢的信號處理流程

OpenJDK 17 源碼&#xff0c;安全點輪詢的信號處理流程如下&#xff08;重點分析安全點輪詢相關部分&#xff09;&#xff1a;核心信號處理流程信號觸發&#xff1a;當線程訪問安全點輪詢內存頁時&#xff08;SafepointMechanism::is_poll_address&#xff09;&#xff0c;會觸…

InfluxDB 在工業控制系統中的數據監控案例(一)

工業控制系統數據監控的重要性**在工業領域&#xff0c;生產過程的復雜性和連續性使得數據監控成為保障生產穩定運行的關鍵環節。通過實時收集、處理和分析生產數據&#xff0c;企業能夠及時掌握設備運行狀態、產品質量信息以及生產流程的各項參數&#xff0c;從而為生產決策提…

嵌入式學習(day26)frambuffer幀緩沖

一、UI技術: User interface&#xff08;1&#xff09;framebuffer: 幀緩沖、幀緩存技術 Linux內核專門為圖形化顯示提供的一套應用程序接口。流程如下&#xff1a;1. 打開顯示設備 (/dev/fb0) 2. 獲取顯示設備相關參數&#xff08;分辨率&#xff0c;像素格式&#xff09;---》…

408每日一題筆記 41-50

答案&#xff1a;A 解析&#xff1a;CSMA/CD 協議里&#xff0c;“爭用期” 就是信號在總線上最遠兩個端點之間往返傳輸的時間&#xff0c;也叫沖突窗口&#xff0c;選 A。

【物聯網】基于樹莓派的物聯網開發【26】——樹莓派開啟串口并配置串口助手Minicom

串口配置 &#xff08;1&#xff09;打開串口&#xff0c;終端輸入命令&#xff1a; sudo raspi-config &#xff08;2&#xff09;串口設置選擇Interfacing Options→Serial port→No→Yes→ok&#xff08;3&#xff09;設置開啟&#xff0c;打開串口 &#xff08;4&#xff0…

考研/考公知識共享平臺的設計與實現-項目分享

考研/考公知識共享平臺的設計與實現-項目分享項目介紹項目摘要學生前臺用例圖管理員用例圖系統流程圖系統功能結構圖實體圖學生信息實體圖資料信息管理實體圖報考指南管理寫在最后項目介紹 使用者&#xff1a;管理員、學生前臺、學生后臺 開發技術&#xff1a;MySQLJavaSpring…

一鍵設置 NTP 時區的腳本(親測,適用于部署 K8S 的前置環境)

文章目錄一、時區和時間同步的配置命令二、完整腳本ntp_timezone_setup.sh三、使用方法3.1、創建腳本3.2、賦予執行權限3.3、運行腳本3.4、驗證一、時區和時間同步的配置命令 整理用于做時區和時間同步的配置幾條命令分別如下&#xff1a; 1?? 編輯 chrony 配置 vim /etc/…

BPMN編輯器技術實現總結AI時代的工作流編輯器

項目概述 基于 diagram.js 的 BPMN 流程設計器&#xff0c;通過依賴注入(DI)實現模塊化擴展&#xff0c;自定義模塊擴展與SVG圖形渲染。后端工作流引擎自定義統一任務調度函數&#xff0c;實現異構模型統一調用。 核心技術架構 1. diagram.js 架構基礎 核心模塊組成 Canv…

兩階段最小二乘法(2SLS)與 工具變量(IV)模型

以下是關于兩階段最小二乘法&#xff08;2SLS&#xff09;與工具變量&#xff08;IV&#xff09;模型關系的系統解析&#xff0c;結合計量經濟學理論與論文上下文進行說明&#xff1a;一、核心關系&#xff1a;2SLS是IV模型的實現方法 1. IV模型&#xff1a;解決內生性的理論框…

熬夜面膜賽道跑出的新物種

在快節奏的現代生活中&#xff0c;熬夜已成為都市人群的常態&#xff0c;深夜11點后的朋友圈總是一片“失眠”哀嚎。隨之而來的是“熬夜肌”問題的激增——暗沉、干燥、屏障受損等訴求催生了龐大的熬夜面膜市場。2025年&#xff0c;中國面膜線上規模已達484億元&#xff0c;其中…

20250813測試開發崗(涼)面

1. 自我介紹2. 你如何理解測開&#xff0c;你認為測開的工作有哪些3. 測試的時候包括哪些部分4. 就功能層面&#xff0c;你認為需要從那些部分考慮&#xff0c;形成一個完整并可執行的trace&#xff08;是這個詞吧&#xff09;5. 你了解數據庫嗎&#xff08;我說只會比較基礎的…

面向Python/C#開發者入門Java與Bukkit API

本教程將以"手持發射器箭矢機槍"功能為例&#xff0c;帶你掌握Java語言基礎和Bukkit API的核心概念&#xff0c;最終實現自主開發插件。 我們將通過剖析一個實際Java代碼文件&#xff0c;逐步解析其運作機制&#xff0c;幫助你順利將現有編程知識遷移到Java和Bukkit…

從100到0.3美元:GPT-5用價格戰血洗大模型賽道

————————— 一、從 100 美元到 0.3 美元&#xff1a;史無前例的效率革命 ————————— 互聯網女王 Mary Meeker 在《AI 趨勢報告 2025》里寫下這組數字&#xff1a; ? 訓練成本 8 年飆升 2400 倍&#xff1b; ? 推理成本 2 年暴跌 99.7%。OpenAI 把“暴跌”推到…

第三十二天(文件操作安全)

文件遍歷上傳下載刪除編輯包含等 $_FILES&#xff1a;PHP中一個預定義的超全局變量&#xff0c;用于在上傳文件時從客戶端接收文件&#xff0c;并將其保存到服務器上。它是一個包含上傳文件信息的數組&#xff0c;包括文件名、類型、大小、臨時文件名等信息。 $_FILES"表…

系統集成項目管理工程師【第十一章 規劃過程組】規劃風險應對、規劃采購管理篇

系統集成項目管理工程師【第十一章 規劃過程組】規劃風險應對、規劃采購管理篇 一、規劃風險應對&#xff1a;為項目穿上"防護衣" 1. 什么是規劃風險應對&#xff1f; 規劃風險應對是基于風險量化分析結果&#xff0c;制定可選方案、選擇應對策略并商定具體行動的過程…