數據結構課程設計---c語言實現通訊錄(動態擴容+文件存儲)

1 題目一 : 通訊錄

1.1問題描述
編寫一個通訊錄管理系統,以把所學數據結構知識應用到實際軟件開發中去。每條信息至包含 :姓名(NAME )街道(STREET)城市(CITY)郵編(EIP)國家(STATE)幾項

1.2.算法設計與分析

1.2.1設計思路分析
根據平常我們使用的通訊錄,我們可以抽象出一個人的一些基本信息,我們把它們封裝成一個結構體,代表一個我們實現的通訊錄中一個人的基本信息應該有哪些內容。然后我們再用一個這個結構體來定義一個結構體數組,就是我們通訊錄的存儲方式。
接下來,我們要實現一些相應的功能
初始化通訊錄:為了方便我們更好的對空間進行管理,擴容或者縮減,所以這里我們采用動態分配空間的方式開辟數組
添加聯系人:按順序輸入要添加的聯系人,輸入完畢后通訊錄當前數量加1
刪除聯系人:遍歷整個通訊錄,找到要刪除的聯系人后刪除,找到,則不刪除
修改聯系人:遍歷整個通訊錄,找到要修改的聯系人后刪除,找到,則不修改
查找聯系人:遍歷整個通訊錄,找到要查找的聯系人,找到打印,否則提示沒找到
打印通訊錄:遍歷整個通訊錄,依次打印聯系人
按姓名(字節序)排序:依照姓名在計算機中的字節序來為聯系人排序
清空所有聯系人:通信錄當前大小記為0

1.2.2設計程序流程圖(要求圖文并茂)

在這里插入圖片描述
進入程序中,先初始化整個通訊錄,隨后進入菜單頁面,選擇相應功能,每次選擇功能并執行完后返回選擇頁面,只有當選擇0時才是退出程序。
1.2.3數據結構定義

typedef struct PeoInfo				//定義個人信息
{char NAME[MAX_NAME];		//姓名int age;					//年齡char CITY[MAX_ADDR];		//城市char sex[MAX_SEX];			//性別char STREET[MAX_STREET];	//街道char EIP[MAX_TELE];			//郵編char STATE[MAX_ADDR];		//國家 
}PeInfo;typedef struct Contact				//定義通訊錄
{PeInfo *array;int sz;      int Capacity;
}Contact;

1.2.4算法的時間復雜度分析
初始化通訊錄:為了方便我們更好的對空間進行管理,擴容或者縮減,所以這里我們采用動態分配空間的方式開辟數組,時間復雜度為O(1)
添加聯系人:按順序輸入要添加的聯系人,輸入完畢后通訊錄當前數量加1.
直接按順序插入,時間復雜度為O(1)
刪除聯系人:遍歷整個通訊錄,找到要刪除的聯系人后刪除,找到,則不刪除,遍歷整個數組,時間復雜度為O(n)
修改聯系人:遍歷整個通訊錄,找到要修改的聯系人后刪除,找到,則不修改,遍歷整個數組,時間復雜度為O(n)
查找聯系人:遍歷整個通訊錄,找到要查找的聯系人,找到打印,否則提示沒找到,遍歷整個數組,時間復雜度為O(n)
打印通訊錄:遍歷整個通訊錄,依次打印聯系人,遍歷整個數組,時間復雜度為O(n)
按姓名(字節序)排序:依照姓名在計算機中的字節序來為聯系人排序,要遍歷整個數組,所以時間復雜度為O(n)
清空所有聯系人:直接將當前大小記為0,時間復雜度為O(1)

1.3源程序清單(帶注釋)

contact.h文件

#define  MAX_NAME  20				//名字數組的大小
#define   MAX_SEX  5				//性別的大小
#define   MAX_TELE 12				
#define    MAX_ADDR  20				//城市和國家的大小
#define   MAX       1000			//通訊錄得最大容量
#define  MAX_STREET  20				//街道的大小#include<string.h>
#include<stdio.h>
#include<assert.h>
#include<windows.h>typedef struct PeoInfo			//定義人的信息
{char NAME[MAX_NAME];		//姓名int age;					//年齡char CITY[MAX_ADDR];		//城市char sex[MAX_SEX];			//性別char STREET[MAX_STREET];	//街道char EIP[MAX_TELE];			//郵編char STATE[MAX_ADDR];		//國家 
}PeInfo;typedef struct Contact			//定義通訊錄的信息
{PeInfo *array;int sz;      int Capacity;
}Contact;enum Option						//枚舉類型,方便調用功能函數
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT,DESTROY
};
//各類功能函數聲明
void InitContact(Contact*  pcon);		
void AddContact(Contact *pcon);
void ShowContact(const Contact* pcon);
void DelContact(Contact* pcon);
void SearchContact( const Contact* pcon);
void ModifyContact(Contact* pcon);
void SortContact(Contact* pcon);
void clearContact(Contact *pcon);
void Load(Contact* pcon);
void Save(Contact* pcon);

contact.c文件

#define  _CRT_SECURE_NO_WARNINGS
#include  "contact.h"void CheckFull(Contact* PhoneBook)					//擴容函數
{if (PhoneBook->sz == PhoneBook->Capacity)		//如果當前通訊錄的大小等于通訊錄的最大容量{printf("聯系人已達上限:%d/%d!\n", PhoneBook->sz, PhoneBook->Capacity);			PeInfo*tmp = (PeInfo*)realloc(PhoneBook->array, sizeof(PeInfo)*(PhoneBook->Capacity + 1));	//重新申請空間,比原來大小多一位if (tmp != NULL)								//提示申請空間成功{PhoneBook->array = tmp;PhoneBook->Capacity = PhoneBook->Capacity + 1;printf("擴容成功!\n");}else											//如果指針為空,則申請空間失敗{printf("擴容失敗!\n");exit(1);}}
}//這里是每次程序運行時,加載儲存在本地txt文檔里的聯系人信息,如果沒有找到這個文檔,就在當前目錄下創建一個txt記事本:
void Load(Contact* pcon)
{FILE* fp = fopen("contact.txt", "r+");			    //打開文件,如果沒有,則創建打開PeInfo temp = { 0 };							//建立一個結構體數組printf("加載聯系人的信息中\n");		if (fp == NULL)														{printf("文件打開失敗!\n");}if (fread(&temp, sizeof(PeInfo), 1, fp))		//讀文件,如果無法讀入,則說明通訊錄已滿需要擴容{CheckFull(pcon);					    	//調擴容函數pcon->array[pcon->sz] = temp;						pcon->sz++;}fclose(fp);printf("數據讀取成功,加載了%d條信息\n", pcon->sz);
}
//這個函數是在程序即將結束前,將修改變動的聯系人信息的操作,儲存在本地文檔中
void Save(Contact* pcon)						
{FILE* fp = fopen("contact.txt", "w+");if (fp == NULL){printf("文件打開失敗!\n");}else{for (int i = 0; i < pcon->sz; i++){/*if (pcon->array[i].NAME[0] != 0)//名字   年齡   性別  郵編  國家  街道  城市fprintf(fp, "%s %s %s %s %s %s %s\n",pcon->array[i].NAME,pcon->array[i].age,pcon->array[i].sex,pcon->array[i].EIP,pcon->array[i].STATE,pcon->array[i].STREET,pcon->array[i].CITY);*/fwrite(pcon->array, sizeof(PeInfo),1,fp);	//寫入文件中}}fclose(fp);//printf("保存成功\n");
}void InitContact(Contact* pcon)							//初始化函數
{pcon->sz = 0;										//通訊錄當前大小置為0pcon->array = (PeInfo *)malloc(sizeof(PeInfo)* MAX);//動態開辟空間pcon->Capacity = MAX;								//設置最大容量//memset(pcon->array, 0, sizeof(PeInfo)* MAX);
}void AddContact(Contact *pcon)							//添加聯系人
{assert(pcon != NULL);								//判斷指針是否為空if (pcon->sz == MAX){								//判斷通訊錄錄是否已滿printf("通訊錄已滿,無法添加.\n");}else{												//如果沒有滿則輸入數據printf("請輸入名字\n");scanf("%s", pcon->array[pcon->sz].NAME);printf("請輸入年齡\n");scanf("%d", &(pcon->array[pcon->sz].age));printf("請輸入性別\n");scanf("%s", pcon->array[pcon->sz].sex);printf("請輸入國家\n");scanf("%s", pcon->array[pcon->sz].STATE);printf("請輸入郵編\n");scanf("%s", pcon->array[pcon->sz].EIP);printf("請輸入城市\n");scanf("%s", pcon->array[pcon->sz].CITY);printf("請輸入街道\n");scanf("%s", pcon->array[pcon->sz].STREET);pcon->sz++;printf("錄入成功!\n");}void ShowContact(const Contact* pcon)					//打印通訊錄
{assert(pcon != NULL);int i = 0;//名字   年齡   性別  郵編  國家  街道  城市printf("%10s\t%4s\t%4s\t%12s\t%15s\t%15s\t%15s\t\n","名字","年齡","性別","郵編","國家","城市","街道");for (i = 0; i < pcon->sz; i++){printf("%10s\t%4d\t%4s\t%12s\t%15s\t%15s\t%15s\t\n",pcon->array[i].NAME,pcon->array[i].age,pcon->array[i].sex,pcon->array[i].EIP,pcon->array[i].STATE,pcon->array[i].CITY,pcon->array[i].STREET);}}int FindEntry(Contact*  pcon, char name[])							    //查詢函數
{ //注意這里  第二個參數是name[]  千萬不能寫成name,要不然程序會崩潰assert(pcon != NULL);int i = 0;for (i = 0; i < pcon->sz; i++){							//遍歷整個數組,找到返回對應下標//找不到if (strcmp(pcon->array[i].NAME, name) == 0){return i ;}}//找到return  -1;											//沒找到,返回1
}
void DelContact(Contact* pcon)								//刪除聯系人
{assert(pcon != NULL);//查找int i = 0;int j = 0;int pos = 0;char name[MAX_NAME] = { 0 };if (pcon->sz == 0){printf("通訊已空,無法刪除:\n");return;}printf("請輸入要刪除人的名字:\n");scanf("%s", name);//查找過程pos=FindEntry(pcon, name);								//調查詢函數if (pos == -1){printf("刪除的人不存在\n");return;}//刪除for (j = pos; j < pcon->sz ; j++){						//找到后,依次往前搬移數組元素pcon->array[j] = pcon->array[j + 1];}pcon->sz--;printf("刪除成功\n");}
void SearchContact(const Contact* pcon)						//查找聯系人
{assert(pcon != NULL);int pos = 0;						char name[MAX_NAME] = { 0 };printf("請輸入要查找人的名字:\n");scanf("%s", name);pos = FindEntry(pcon, name);							//調查詢函數if (pos == -1){printf("要查找人的信息不存在\n");}else													//找到打印{printf("%10s\t%4s\t%4s\t%12s\t%15s\t%15s\t%15s\t\n", "名字", "年齡", "性別", "郵編", "國家", "城市", "街道");printf("%10s\t%4d\t%4s\t%12s\t%15s\t%15s\t%15s\t\n",pcon->array[pos].NAME,pcon->array[pos].age,pcon->array[pos].sex,pcon->array[pos].EIP,pcon->array[pos].STATE,pcon->array[pos].CITY,pcon->array[pos].STREET);}
}
void ModifyContact(Contact* pcon)							//修改聯系人
{assert(pcon != NULL);int pos = 0;char name[MAX_NAME] = { 0 };printf("請輸入要修改人的名字:\n");scanf("%s", name);pos = FindEntry(pcon, name);							//調查詢函數if (pos == -1){printf("要修改人的信息不存在\n");}else													//找到則修改{printf("請輸入名字\n");scanf("%s", pcon->array[pos].NAME);printf("請輸入年齡\n");scanf("%d", &(pcon->array[pos].age));printf("請輸入性別\n");scanf("%s", pcon->array[pos].sex);printf("請輸入國家\n");scanf("%s", pcon->array[pos].STATE);printf("請輸入郵編\n");scanf("%s", pcon->array[pos].EIP);printf("請輸入城市\n");scanf("%s", pcon->array[pcon->sz].CITY);printf("請輸入街道\n");scanf("%s", pcon->array[pcon->sz].STREET);printf("修改成功\n");}
}
void SortContact(Contact* pcon)   //按名字排序
{int i = 0;assert(pcon);//趟數for (i = 0; i < pcon->sz - 1; i++){int flag = 1;  //表示已經排好序int j = 0;for (j = 0; j < pcon->sz - 1 - i; j++){if (strcmp(pcon->array[j].NAME, pcon->array[j + 1].NAME)>0)	//比較兩個名字的字節序大小{PeInfo tmp = pcon->array[j];pcon->array[j] = pcon->array[j + 1];pcon->array[j + 1] = tmp;flag = 0;  //表明之前無序}}if (flag == 1){break;}}printf("排序完成\n");
}
void clearContact(Contact *pcon)			//刪除通訊錄中全部信息
{assert(pcon);int flag = 0;while (1){printf("請問你確定要刪除整個通訊錄嗎?\n");printf("1:刪除,0:不刪除\n");scanf("%d", &flag);if (flag == 1){pcon->sz = 0;printf("通訊錄已刪除\n");break;}else{break;}}
}

test.c文件

#define  _CRT_SECURE_NO_WARNINGS
#include "contact.h"					//包含頭文件#include<stdio.h>void  menu(){							 //菜單函數printf("****************************************\n");printf("***1 添加聯系人         2  刪除聯系人 **\n");printf("***3 查詢聯系人         4 修改聯系人  **\n");printf("***5 查看當前通訊錄     6 排序        **\n");printf("***7 刪除通訊錄		0 退出        **\n");printf("****************************************\n");}
void test(){							//主功能程序//創建通訊錄Contact con;//初始化InitContact(&con);Load(&con);int input = 0;do{ menu();printf("請選擇:\n");scanf("%d", &input);switch (input ){case ADD:AddContact(&con);break;case DEL:DelContact(&con);break;case SHOW :ShowContact(&con);break;case SEARCH:SearchContact(&con);break;case MODIFY :ModifyContact(&con);break;case SORT:SortContact(&con);break;case EXIT:printf("退出\n");break;case DESTROY:clearContact(&con);break;default:printf("選擇錯誤\n");break;}} while (input);Save(&con);				//保存信息到文件中printf("保存成功\n");free(con.array);
}int  main()						//主函數
{test();system("pause");return 0;
}

1.4執行結果

1.添加聯系人
在這里插入圖片描述
2刪除聯系人
在這里插入圖片描述
3查詢聯系人
在這里插入圖片描述
4修改聯系人
在這里插入圖片描述
5查看當前通訊錄
在這里插入圖片描述
6排序聯系人(按字節序排序)
在這里插入圖片描述
7刪除通訊錄
在這里插入圖片描述
0 退出
在這里插入圖片描述

1.5存在問題分析

1.通訊錄中無法分辨同名同姓的情況。
2 通訊錄沒有一個圖形化界面,用戶需要手動輸入相關命令,無法實現鼠標點擊。

1.6結論

已經可以實現通訊錄的基本功能,但在數據處理和用戶操作上具有一些問題。

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

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

相關文章

linux內核panic

1. Linux Kernel Panic的產生的原因 panic是英文中是驚慌的意思&#xff0c;Linux Kernel panic正如其名&#xff0c;linux kernel不知道如何走了&#xff0c;它會盡可能把它此時能獲取的全部信息都打印出來。 有兩種主要類型kernel panic&#xff0c;后面會對這兩類panic做詳細…

數據結構課程設計------c實現散列表(二次探測再哈希)電話簿(文件存儲)

題目二 &#xff1a;散列表的設計與實現 2.1問題描述 設計散列表實現電話號碼查找系統&#xff0c;使得平均查找長度不超過2基本要求 &#xff08;1&#xff09;設每個記錄有下列數據項&#xff1a;電話號碼、用戶名、地址&#xff1b; &#xff08;2&#xff09;從鍵盤輸入各…

科技論文----論搜索引擎現狀及發展趨勢

搜索引擎現狀及發展趨勢 【摘要】 隨著最近10年中國互聯網的快速發展菜互聯網已經徹底改變了人們的生活方式&#xff0c;而在互聯網的發展過程中。搜索引擎發揮了巨大的推動作用。本文對搜索引擎的發展歷史采用的技術&#xff0c;發展現狀出現的問題以及未來發展方向進行了綜述…

inittab文件格式

/etc/inittab文件是Linux系統第一個進程init的配置文件。其每個記錄占一行&#xff0c;每行最多512個字符。該文件的每個記錄的格式為&#xff1a; id:runlevel:action:process 其中&#xff0c;id是一個不超過4個字符的標識&#xff0c;用來唯一標識一條記錄。runlevel表明該條…

數據結構課程設計------掃雷游戲(升級版,可展開)

本程序由團隊中的一個人所寫&#xff0c;本人看懂并寫下此文章 題目&#xff1a;掃雷 3.1問題描述 掃雷游戲 [基本要求] &#xff08;1&#xff09;完成棋盤的初始化并在標準顯示器中顯示 &#xff08;2&#xff09;通過輸入行列值確定用戶輸入 &#xff08;3&#xff09;游…

C語言的編譯鏈接過程的介紹

發布時間: 2012-11-08 10:17 作者: 未知 來源: 51Testing軟件測試網采編 字體: 小 中 大 | 上一篇 下一篇 | 打印 | 我要投稿 | 推薦標簽&#xff1a; DotNet 軟件開發 | 感言十年 C語言的編譯鏈接過程要把我們編寫的一個c程序&#xff08;源代碼&#x…

vs2013鏈接Mysql時出現 (由于找不到libmysql.dll,無法繼續執行代碼。重新安裝程序可能會解決此問題)

將MySQL安裝目錄下的lib文件夾中 的libmysql.dll文件拷貝到C:\Windows\System32目錄下即可

gcc 優化選項 -O1 -O2 -O3 -Os 優先級,-fomit-frame-pointer

少優化->多優化&#xff1a; O0 -->> O1 -->> O2 -->> O3 -O0表示沒有優化,-O1為缺省值&#xff0c;-O3優化級別最高 英文解析&#xff1a; -O -O1 Optimize. Optimizing compilation takes somewhat more time, an…

const 和 #define 區別總結

const有類型&#xff0c;可進行編譯器安全檢查&#xff0c;#define 無類型&#xff0c;不可進行類型檢查const 有作用域&#xff0c;而#define 不重視作用域&#xff0c;默認定義在指定作用域下有效的常量&#xff0c;那么#define 就不能用&#xff08;可以用#undef結束宏定義生…

Eclipse : Unresolved inclusion

Eclipse 中新建C 或C 到項目時&#xff0c;頭文件報警&#xff0c;顯示“Unresolved inclusion:<stdio.h>” 雖然不影響項目到編譯和運行&#xff0c;確也無法查看頭文件&#xff0c;讓人感覺實在不爽。下面是在國外到網站上看到解決方案&#xff0c;自己整理了一下拿來分…

c++對const增強 和cosnt分配內存情況

const增強 c語言中const是偽常量&#xff0c;可以通過指針修改 c中const會放到符號表中 c語言中const默認是外部連接&#xff0c;c中const默認是內部鏈接 #include<iostream> using namespace std;const int m_a 10; //在全局區域里&#xff0c;受到保護&…

Linux下crontab命令的用法

任務調度的crond常駐命令 crond 是linux用來定期執行程序的命令。當安裝完成操作系統之后&#xff0c;默認便會啟動此任務調度命令。crond命令每分鍾會定期檢查是否有要執行的工作&#xff0c;如果有要執行的工作便會自動執行該工作。而linux任務調度的工作主要分為以下兩類&am…

c++中引用的作用

引用的基本語法 用途起別名 Type &別名原名 引用必須初始化 一旦初始化后&#xff0c;不能修改 對數組建立引用 #include<iostream>using namespace std;//1.引用基本語法 Type &別名原名void test01(){int a 10;int &b a;cout << "a"…

LVM (Logic Volume Management,邏輯卷管理)

是傳統商業Unix就帶有的一項高級磁盤管理工具&#xff0c;異常強大。后來LVM移植到了Linux操作系統上&#xff0c;盡管不像原來Unix版本那么強大&#xff0c;但瘦死的駱駝比馬大&#xff0c;Linux的LVM仍然非常強大&#xff0c;可以在生產運行系統上面直接在線擴展硬盤分區&…

cpu中的MMU的作用

虛擬內存與物理內存之間的映射 用戶空間映射到物理內存是獨立的&#xff0c;提高安全性修改內存訪問級別 &#xff08;0是最高級&#xff09;

Linux命令行與Shell腳本編程大全讀書筆記

Linux內核4大主要功能&#xff1a; 內存管理 進程管理 設備管理 文件系統管理 Linux系統啟動的進程和腳本管理 1./etc/inittab 管理系統開機時會自動啟動的進程 2./etc/init.d 管理開機時啟動或停止某個應用的腳本放在這個目錄下&#xff0c;/etc/rcX.d目錄在啟動時&…

拷貝構造函數的總結

構造函數的分類及調用 按照參數分類 1.無參構造&#xff08;默認構造&#xff09; 2.有參構造按照類型分類 1.普通構造函數2.拷貝構造函數無參構造寫法和調用 Person p1; 注意不能寫Person (),因為編譯器認為這個是函數聲明有參構造函數寫法 和調用 Person p2(10) 或者Per…

技術與技巧札記

Linux常用命令及技巧&#xff1a; &#xff08;1&#xff09;cat /proc/version 查看當前內核的版本 (2) 掛載nfs文件夾&#xff1a;需要先確認在&#xff0f;etc&#xff0f;exports文件&#xff0c;可以用于開發板掛載的文件夾 mount -o nolock 10.0.22.30:/root/sharednfs …

c++中new的總結(動態管理,malloc存在的問題,malloc與new的區別)

c中使用malloc出現的問題 程序員必須確定對象的長度malloc 返回一個&#xff08;void *&#xff09;指針 &#xff0c;c不允許將&#xff08;void*) 賦值給其它指針&#xff0c;必須強轉malloc可能申請內存失敗&#xff0c;所以必須判斷返回值來保存內存分配成功用戶在使用對象…

Linux中變量#,@,0,1,2,*,$$,$?的含義

$# 是傳給腳本的參數個數 $0 是腳本本身的名字 $1 是傳遞給該shell腳本的第一個參數 $2 是傳遞給該shell腳本的第二個參數 $ 是傳給腳本的所有參數的列表 $* 是以一個單字符串顯示所有向腳本傳遞的參數&#xff0c;與位置變量不同&#xff0c;參數可超過9個 $$ 是腳本運行的當前…