通訊錄中每個通訊者的資訊包括編号、姓名、性别、電話、E-mail位址;采用單連結清單結構存儲,實作以下功能:
1.通訊錄的建立
2.通訊者資訊的插入
3.通訊者資訊的查詢
4.通訊者資訊的删除
5.通訊錄的輸出
其中,通訊者資訊的查詢包括按編号查詢和按姓名查詢;通訊錄的輸出按編号排序。并要求每個功能是一個子產品,有主要菜單,可使用數字來選擇菜單項,分别進入相應的功能。
個人資料結構課程設計作業,如遇到本校校友,還請稍微更改。
交流群:970353786
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma warning(disable:4996)//用于屏蔽序号4996的錯誤
typedef struct phone
{
char ID[10]; //編号
char name[20]; //姓名
char tel[15]; //電話
char sex[2];//性别
char email[20]; //email郵箱
}Ipa;//給存放通訊錄屬性的結構體取個别名
//鍊棧定義
typedef struct List
{
Ipa data;//資料域
struct List *next;//指針域
}List;
List *L = NULL;//初始化為空
//1.初始化通訊錄,建立頭節點
void InitList()
{
L = (List *)malloc(sizeof(List));//建立頭節點并且配置設定動态記憶體
L->next = NULL;//頭結點下一個初始化為空
printf("初始化成功!\n");
}
//2.插入資料,建立通訊錄(頭插法),參考資料結構書上23頁
void CreateList_Head()
{
List *node; //插入節點
int count = 0;//初始化為0,用于記錄資料條數
int flag = 1;//用于判斷是否繼續輸入下一條記錄
while (flag)//為1就執行以下語句
{
count++;
node= (List *)malloc(sizeof(List));//建立頭節點
printf("插入第%d條記錄:\n", count);
printf("ID:");
scanf("%s", &(node->data.ID));//輸入編号
//判斷ID是否重複
List *p = L->next;
while (p)
{
//strcmp為比較函數 基本形式為strcmp(str1,str2),若str1=str2,則傳回零
if (strcmp(p->data.ID, node->data.ID) == 0)//比較目前編号是否與已有的編号對比
{
printf("ID重複,請重新輸入!\n");
printf("ID:");//重新輸入編号
scanf("%s", &(node->data.ID));
}
else
p = p->next;//沒重複則可跳到下一個位置執行
}
//編号未沖突則開始資訊錄入
printf("姓名:");
scanf("%s", &(node->data.name));
printf("性别:");
scanf("%s", &(node->data.sex));
printf("電話:");
scanf("%s", &(node->data.tel));
printf("郵箱:");
scanf("%s", &(node->data.email));
node->next = L->next;
L->next = node;
printf("是否繼續錄入(1.繼續 0.完成錄入):");
scanf("%d", &flag);
if (flag == 0)
break;
}
}
//3.插入資料,建立通訊錄(尾插法),
void CreateList_Tail()
{
List *node, *tail; //插入節點和尾節點
tail = L;
int count = 0;
int flag = 1;
while (flag)
{
count++;
node = (List *)malloc(sizeof(List)); //給節點配置設定空間
printf("錄入第%d條資料:", count);
printf("ID:");
scanf("%s", &(node->data.ID));
//判斷ID是否重複
List *p = L->next;
while (p)
{
if (strcmp(p->data.ID, node->data.ID) == 0)
{
printf("ID重複,請重新輸入!\n");
printf("ID:");
scanf("%s", &(node->data.ID));
}
else
p = p->next;
}
printf("姓名:");
scanf("%s", &(node->data.name));
printf("性别:");
scanf("%s", &(node->data.sex));
printf("電話:");
scanf("%s", &(node->data.tel));
printf("郵箱:");
scanf("%s", node->data.email);
tail->next = node;
node->next = NULL;
tail = node;
printf("是否繼續錄入(1.繼續 0:結束):");
scanf("%d", &flag);
if (flag == 0)
break;
}
}
//4.删除資料(根據姓名删除),即删除節點
void DelList()
{
List *p = L->next;//指向下一個
List *q = L;
char ID[10];//編号範圍不能超出十位數
printf("請輸入要删除的ID:");
scanf("%s", &ID);
while (p && strcmp(p->data.ID, ID) != 0)//比較編号是否沖突
{
p = p->next;
q = q->next;
}
if (p)
{
q->next = p->next;
printf("删除成功!\n");
printf("被删除資料的資訊為:\n");
printf("ID:%s\n", p->data.ID);
printf("姓名:%s\n", p->data.name);
printf("性别:%s\n", p->data.sex);
printf("電話:%s\n", p->data.tel);
printf("郵箱:%s\n", p->data.email);
free(p);//釋放删除的p
}
else
{
printf("通訊錄中不存在此人資訊!\n");
}
}
//5.插入資料(前插法)
void InsertList_Pre()
{
List *p, *q, *r, *node;
p = L->next;
q = L;
char ID[10];
printf("請輸入要插入的位置(輸入該位置的ID):");
scanf("%s", &ID);
while (p && strcmp(p->data.ID, ID) != 0)//比較編号是否沖突
{
p = p->next;
q = q->next;
}
if (p != NULL)
{
//給新節點配置設定空間
node = (List*)malloc(sizeof(List));
//錄入新節點資料
printf("請輸入新節點資訊:\n");
judge:
printf("ID:");
scanf("%s", &(node->data.ID));
//判斷ID是否重複
r = L->next;
while (r && strcmp(r->data.ID, node->data.ID) != 0)
{
r = r->next;
}
if (r != NULL)
{
printf("ID重複,請重新輸入!\n");
//free(r); 這裡不能free(r),如果釋放r,會失去r的下一個節點的資訊,連結清單會被破壞
goto judge;
}
printf("姓名:");
scanf("%s", &(node->data.name));
printf("性别:");
scanf("%s", &(node->data.sex));
printf("電話:");
scanf("%s", &(node->data.tel));
printf("郵箱:");
scanf("%s", &(node->data.email));
}
else
{
//如果沒有該ID
int choice1;
printf("通訊錄中未找到該ID,是否使用預設方式将新節點插入到最後(1.是 0.否):");
scanf("%d", &choice1);
if (choice1 == 1)
{
//給新節點配置設定空間
node = (List *)malloc(sizeof(List));
//給新節點輸入資料
printf("請輸入新節點資訊:\n");
judge1:
printf("ID:");
scanf("%s", &(node->data.ID));
//判斷ID是否重複
r = L->next;
while (r && strcmp(r->data.ID, node->data.ID) != 0)
{
r = r->next;
}
if (r != NULL) //ID重複
{
printf("ID重複,請重新輸入!\n");
goto judge1;
}
printf("姓名:");
scanf("%s", &(node->data.name));
printf("性别:");
scanf("%s", &(node->data.sex));
printf("電話:");
scanf("%s", &(node->data.tel));
printf("郵箱:");
scanf("%s", &(node->data.email));
}
else
return;
}
node->next = q->next;
q->next = node;
printf("插入成功!\n");
}
//6.插入資料(後插法)
void InsertList_Back()
{
List *p, *r, *q, *node;
p = L->next;
q = L;
char ID[10];
printf("請輸入要插入的位置(輸入該位置的ID):");
scanf("%s", &ID);
while (p && strcmp(p->data.ID, ID) != 0)
{
p = p->next;
q = q->next;
}
if (p != NULL)
{
//為新節點配置設定空間
node = (List*)malloc(sizeof(List));
//為新節點輸入資料
printf("請輸入新節點資訊:\n");
judge:
printf("ID:");
scanf("%s", &(node->data.ID));
//判斷ID是否重複
r = L->next;
while (r && strcmp(r->data.ID, node->data.ID) != 0)
{
r = r->next;
}
if (r != NULL)
{
printf("ID重複,請重新輸入!\n");
goto judge;
}
printf("姓名:");
scanf("%s", &(node->data.name));
printf("性别:");
scanf("%s", &(node->data.sex));
printf("電話:");
scanf("%s", &(node->data.tel));
printf("郵箱:");
scanf("%s", &(node->data.sex));
node->next = p->next;
p->next = node;
printf("插入成功!\n");
}
else
{
//通訊錄中未找到該ID
int choice2;
printf("通訊錄中未找到該ID,是否使用預設方式将該節點插入到最後(1.是 0.否):");
scanf("%d", &choice2);
if (choice2 == 1)
{
//為新節點配置設定空間
node = (List *)malloc(sizeof(List));
//為新節點錄入資訊
printf("請輸入新節點資訊:\n");
judge1:
printf("ID:");
scanf("%s", &(node->data.ID));
//判斷ID是否重複
r = L->next;
while (r && strcmp(r->data.ID, node->data.ID) != 0)
{
r = r->next;
}
if (r != NULL) //ID重複
{
printf("ID重複,請重新輸入!\n");
goto judge1;
}
printf("姓名:");
scanf("%s", &(node->data.name));
printf("性别:");
scanf("%s", &(node->data.sex));
printf("電話:");
scanf("%s", &(node->data.tel));
printf("郵箱:");
scanf("%s", &(node->data.email));
node->next = q->next;
q->next = node;
}
if (choice2 == 0)
return;
}
}
//7.修改通訊錄資料
void UpdateList()
{
List *p;//配置設定指針
p = L->next;
char ID[10];
printf("請輸入要修改的ID:");
scanf("%s", &ID);
while (p && strcmp(p->data.ID, ID) != 0)//如果p真且編号不沖突
{
p = p->next;//指向下一個
}
if (p != NULL)//p為空條件下
{
int choice;
printf("請輸入需要修改的屬性(1.姓名 2.性别 3.電話 4.郵箱):");
scanf("%d", &choice);
if (choice == 1)
{
printf("請輸入新的姓名:");
scanf("%s", &(p->data.name));
}
if (choice == 2)
{
printf("請輸入新的聯系人性别:");
scanf("%s", &(p->data.sex));
}
if (choice == 3)
{
printf("請輸入新的電話:");
scanf("%s", &(p->data.tel));
}
if (choice == 4)
{
printf("請輸入新的郵箱:");
scanf("%s", &(p->data.email));
}
printf("更新成功!\n");
}
else
{
printf("通訊錄中不存在該ID!\n");
return;
}
}
//8.查找通訊錄中的資料(通過ID查找)
void SearchList()
{
List *p;
char ID[10];
p = L->next;
printf("請輸入要查找的ID:");
scanf("%s", &ID);
while (p && strcmp(p->data.ID, ID) != 0)
{
p = p->next;
}
if (p == NULL)
{
printf("通訊錄中不存在此人!\n");
return;
}
else
{
printf("ID:%s\t", p->data.ID);
printf("姓名:%s\t", p->data.name);
printf("性别:%s\t", p->data.sex);
printf("電話:%s\t", p->data.tel);
printf("郵箱:%s\n", p->data.email);
}
}
//9.周遊通訊錄
void TraverseList()
{
List *p;
if (L == NULL)
{
printf("通訊錄為空!\n");
return;
}
else
{
p = L->next;
printf("通訊錄中全部資訊如下:\n");
while (p)//循環周遊
{
printf("ID:%s\t", p->data.ID);
printf("姓名:%s\t", p->data.name);
printf("性别:%s\t", p->data.sex);
printf("電話:%s\t", p->data.tel);
printf("郵箱:%s\n", p->data.email);
p = p->next;
}
}
}
//10.釋放連結清單
void DestroyList()
{
List *p, *q;
p = L->next;
while (p)
{
q = p;//用q暫時存放該節點
p = p->next; //p指向下一個節點
free(q);// 釋放目前節點
q = NULL;
}
free(p);
free(L);
L = NULL;
printf("釋放成功!\n");
}
void Menu()
{
printf("\t\t\t****************************************************\n");
printf("\t\t\t1.初始化通訊錄 2.建立通訊錄\n");
printf("\t\t\t3.删除聯系人 4.修改聯系人\n");
printf("\t\t\t5.查找聯系人 6.插入聯系人\n");
printf("\t\t\t7.周遊通訊錄 8.釋放通訊錄\n");
printf("\t\t\t****************************************************\n");
}
int main()
{
int choice;
while (1)
{
Menu();
printf("請選擇菜單:");
scanf("%d", &choice);
switch (choice)
{
case 1:
{
//初始化通訊錄
InitList();
break;
}
case 2:
{
//建立通訊錄
int num;
printf("請選擇建立方式(1.頭插法 2.尾插法):");
scanf("%d", &num);
if (num == 1)
{
//頭插法
CreateList_Head();
break;
}
if (num == 2)
{
//尾插法
CreateList_Tail();
break;
}
}
case 3:
{
//删除資訊
DelList();
break;
}
case 4:
{
//修改資訊
UpdateList();
break;
}
case 5:
{
//查找資訊
SearchList();
break;
}
case 6:
{
//插入資訊
int num;
printf("請選擇插入方式(1.前插法 2.尾插法 3.後插法):");
scanf("%d", &num);
if (num == 1)
{
//前插法
InsertList_Pre();
break;
}
if (num == 2)
{
//後插法
InsertList_Back();
break;
}
}
case 7:
{
//周遊通訊錄
TraverseList();
break;
}
case 8:
{
//釋放通訊錄
DestroyList();
break;
}
default:
break;
}
}
}
示範:
