學習完了單鏈表的基本操作後,我掌握了其增刪改查等基本操作。基於這些操作,我用實現了簡易通訊錄管理系統。包含初始化、添加、刪除、打印、搜索、排序和修改等功能。以下爲源代碼(測試環境爲VS2013):
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int count = 0;//計數
typedef struct PersonNode
{
int pid;//聯繫人的序號(節點序號)
char name[20]; //姓名
int age; //年齡
char phone_num[20]; //手機號碼
struct PersonNode* next; //指向下一個結構體的指針
}PersonNode;
typedef struct SList
{
struct PersonNode* first;
}SList;
//初始化通訊錄
void Init(SList* list)
{
list->first = NULL;
printf("通訊錄初始化成功!\n");
}
//添加聯繫人(單鏈表的尾插)
void AddPerson(SList* list)
{
char c;
PersonNode* Node;
PersonNode* p = list->first;
do
{
//申請新節點用來存儲聯繫人的信息
Node = (PersonNode*)malloc(sizeof(PersonNode));
printf("請輸入聯繫人姓名:");
scanf("%s", &Node->name);
printf("請輸入聯繫人年齡:");
scanf("%d", &Node->age);
printf("請輸入聯繫人手機號碼:");
scanf("%s", &Node->phone_num);
//美申請一個節點,count自加,再賦值給pid
count++;
Node->pid = count;
//將新申請的節點鏈接到鏈表尾部,再使新節點的next指向空
Node->next = NULL;
if (p == NULL)
{
//若添加時此通訊錄是空的
list->first= Node;
p = list->first;
}
else
{
while (p->next != NULL)
{
//尋找最後一個節點進行尾插
p = p->next;
}
p->next = Node;
}
printf("是否繼續添加?(Y/N):");
while ((c = getchar()) != EOF && c != '\n'); //清除緩衝區內容
c = getchar();
} while (c == 'Y'||c=='y');
return;
}
//刪除聯繫人
void DelPerson(SList* list)
{
int num = 0;
PersonNode* prev = NULL;
PersonNode* cur = list->first;
//若通訊錄爲空
if (list->first == NULL)
{
printf("通訊錄爲空,刪除失敗!\n");
return;
}
printf("請輸入想要刪除的序號: ");
scanf("%d", &num);
//若通訊錄不空且還沒有匹配到序號
while (cur != NULL && cur->pid != num)
{
prev = cur;
cur = cur->next;
}
//若要刪除的序號不存在(已經遍歷完了整個鏈表)
if (cur == NULL)
{
printf("輸入的序號有誤,刪除失敗!\n");
return;
}
//若要刪除的聯繫人即爲第一個
if (prev == NULL)
{
//頭刪
PersonNode* old_node = list->first;
list->first = list->first->next;
free(old_node);
count--;
printf("刪除成功!\n");
return;
}
//否則,若刪除的爲中間某一節點
prev->next = cur->next;
free(cur);
printf("刪除成功!\n");
count--;
}
//打印聯繫人
void PrintPerson(SList* list)
{
PersonNode* p ;
p = list->first;
int i = 0;//計數器
printf("序號\t\t姓名\t\t年齡\t\t手機號碼 \n");
printf("====\t\t======\t\t====\t\t===========\n");
for (p = list->first; p != NULL; p = p->next)
{
i++;
printf("%2d\t\t%s\t\t%d\t\t%s\n",i, p->name, p->age, p->phone_num);
}
printf("共有%d條記錄!\n", count);
return;
}
//查找
int Find(char* name, SList* list)
{
int i = 0;
PersonNode* cur = list->first;
for (i = 1,cur=list->first; i <= count,cur!=NULL; i++,cur=cur->next)
{
//若姓名匹配
if (strcmp(name, cur->name) == 0)
{
return 1;
}
}
//查找失敗
return -1;
}
//搜索聯繫人
void SearchPerson(SList* list)
{
PersonNode* cur = list->first;
int tmp = 0;//定義臨時變量來接收Find函數的返回值
int n = 0;//臨時計數器
char name[20] = "0";
//若還沒有錄入
if (list->first == NULL)
{
printf("通訊錄爲空,搜索失敗!\n");
return;
}
printf("請輸入聯繫人的姓名來進行搜索: ");
scanf("%s", name);
if (-1 == Find(name, list))
{
printf("查詢失敗!\n");
}
else
{
printf("序號\t\t姓名\t\t年齡\t\t手機號碼 \n");
printf("====\t\t======\t\t====\t\t===========\n");
for (cur = list->first; cur != NULL; cur = cur->next)
{
if (strcmp(cur->name, name) == 0)
{
n++;
printf("%2d\t\t%s\t\t%d\t\t%s\n", n, cur->name, cur->age, cur->phone_num);
}
}
printf("共有%d條記錄!\n", n);
}
}
//聯繫人排序
void SortPerson(SList* list)
{
//若通訊錄還沒有聯繫人
if (list->first == NULL)
{
printf("通訊錄爲空,排序失敗!\n");
return;
}
//若通訊錄只有一個人
if (list->first->next == NULL)
{
printf("排序成功!\n");
return;
}
//若通訊錄裏有多個聯繫人
PersonNode* cur = NULL;
PersonNode* tail = NULL;
cur = list->first;
while (cur != tail)
{
while (cur->next != tail)
{
if (cur->age > cur->next->age)
{
//交換姓名
char tmp1[20] = "0";
strcpy(tmp1, cur->name);
strcpy(cur->name, cur->next->name);
strcpy(cur->next->name, tmp1);
//交換年齡
int temp = 0;
temp = cur->age;
cur->age = cur->next->age;
cur->next->age = temp;
//交換手機號碼
char tmp2[20] = "0";
strcpy(tmp2, cur->phone_num);
strcpy(cur->phone_num, cur->next->phone_num);
strcpy(cur->next->phone_num, tmp2);
}
cur = cur->next;
}
//cur找到最後一個節點,使tail指向最後的節點,
//再使cur從鏈表頭部開始遍歷
tail = cur;
cur = list->first;
}
printf("排序成功!\n");
}
//修改聯繫人信息
void ModifyPerson(SList* list)
{
char name[15] = "0";
char new_name[15] = "0";
int new_age = 0;
char new_phone_num[20] = "0";
int choice = 0;
//若聯繫人爲空
if (list->first == NULL)
{
printf("通訊錄爲空,修改失敗!\n");
return;
}
//若通訊錄不爲空
//通過cur指針來遍歷鏈表,找到欲修改的節點然後再操作
PersonNode * cur = list->first;
//先根據名字查詢聯繫人
printf("請輸入你想要修改的聯繫人的姓名: ");
scanf("%s", name);
while (cur != NULL)
{
//若匹配成功
if (strcmp(name, cur->name) == 0)
{
printf("請選擇你想要修改的信息的標號: 1.姓名 2.年齡 3.手機號碼: ");
scanf("%d", &choice);
if (1 == choice)
{
printf("請輸入新的姓名: ");
scanf("%s", new_name);
strcpy(cur->name, new_name);
}
if (2 == choice)
{
printf("請輸入新的年齡: ");
scanf("%d", &new_age);
cur->age = new_age;
}
if (3 == choice)
{
printf("請輸入新的手機號碼: ");
scanf("%s", new_phone_num);
strcpy(cur->phone_num, new_phone_num);
}
printf("修改成功!\n");
return;
}
cur = cur->next;
}
printf("查詢失敗!通訊錄無此聯繫人!\n");
return;
}
//菜單
void menu()
{
printf(" ----------歡迎使用Romeo的通訊錄----------\n");
printf(" 0.數據初始化 1.添加聯繫人 \n");
printf(" 2.刪除聯繫人 3.打印聯繫人 ");
printf(" 4.搜索聯繫人 5.聯繫人排序 ");
printf(" 6.修改聯繫人 7.退出通訊錄 ");
printf(" ----------------Romeo製作----------------\n");
}
int main()
{
SList list;
int select = 0;
while (1)
{
menu();
printf("請輸入相應的選項: ");
scanf("%d", &select);
switch (select)
{
case 0: Init(&list);
break;
case 1: AddPerson(&list);
break;
case 2:DelPerson(&list);
break;
case 3: PrintPerson(&list);
break;
case 4: SearchPerson(&list);
break;
case 5: SortPerson(&list);
break;
case 6: ModifyPerson(&list);
break;
case 7:
printf("即將退出本系統,謝謝您的使用!\n");
system("pause");
return 0;
default:printf("輸入有誤,請重新輸入!\n");
break;
}
}
system("pause");
return 0;
}
運行結果:
初始化:
添加聯繫人:
打印聯繫人:
刪除並打印結果:
搜索聯繫人:
聯繫人排序(按年齡從小到大):
修改聯繫人: