用單鏈表實現通訊錄
阿新 • • 發佈:2019-02-06
/*********************************************************************************************************************************
File Name: ******
Author: *** Date: 2016-12-08
Description: 用連結串列實現通訊錄功能
Functionlist: Create_List_Tail();//新增好友
SelectSort(); //對好友進行升序排序
Search(); //查詢好友
Delete_Node(); //刪除好友
DisPlayAll(); //顯示所有好友資訊
DisPlay(); //列印當前建立好友
Meun(); //主選單
FunMeun(); //功能選單
main(); //主函式
***********************************************************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OK 0
#define ERROR -1
#define MALLOC_ERROR -2
typedef struct node
{
long ID; //ID號
char Name[20]; //姓名
char MobNum[13]; //手機號碼
char Addr[50]; //地址
char CpyNum[13]; //公司電話
struct node *next; //結點指標
}Node;
typedef Node *PNode; //重新命名結點指標型別
//尾插法建立連結串列(新增好友資訊)
int Create_List_Tail(PNode h, long ID, char *Name, char *MobNum, char *Addr, char *CpyNum)
{
if (h == NULL)
{
return ERROR;
}
PNode node = (PNode)malloc(sizeof(Node)/sizeof(char));
if (node == NULL)
{
return MALLOC_ERROR;
}
printf("建立使用者\n");
printf ("請輸入ID: ");
scanf ("%ld", &node->ID);
printf ("請輸入姓名: ");
scanf ("%s", node->Name);
printf ("請輸入手機號碼: ");
scanf ("%s", node->MobNum);
printf ("請輸入家庭地址: ");
scanf ("%s", node->Addr);
printf ("請輸入公司電話: ");
scanf ("%s", node->CpyNum);
node->next = NULL;
//找到最後一個結點
PNode temp = h;
while (temp->next)
{
temp = temp->next;
}
temp->next = node;
return OK;
}
//對連結串列用選擇排序法進行升序排序(通過ID號)
PNode SelectSort(PNode head)
{
PNode first; //排列後有序鏈的表頭指標
PNode tail; //排列後有序鏈的表尾指標
PNode p_min; //保留鍵值更小的節點的前驅節點的指標
PNode min; //儲存最小節點
PNode p; //當前比較的節點
first = NULL;
while(head != NULL) //在連結串列中找鍵值最小的節點
{
//注意:這裡for語句就是體現選擇排序思想的地方
for (p = head, min = head; p->next != NULL; p = p->next) //迴圈遍歷連結串列中的節點,找出此時最小的節點
{
if ((p->next->ID) < (min->ID)) //找到一個比當前min小的節點
{
p_min = p; //儲存找到節點的前驅節點:顯然p->next的前驅節點是p
min = p->next; //儲存鍵值更小的節點
}
}
//上面for語句結束後,就要做兩件事;一是把它放入有序連結串列中;二是根據相應的條件判斷,安排它離開原來的連結串列
//第一件事
if (first == NULL) //如果有序連結串列目前還是一個空連結串列
{
first = min; //第一次找到鍵值最小的節點
tail = min; //注意:尾指標讓它指向最後的一個節點
}
else //有序連結串列中已經有節點
{
tail->next = min; //把剛找到的最小節點放到最後,即讓尾指標的next指向它
tail = min; //尾指標也要指向它
}
//第二件事
if (min == head) //如果找到的最小節點就是第一個節點
{
head = head->next; //顯然讓head指向原head->next,即第二個節點,就OK
}
else //如果不是第一個節點
{
p_min->next = min->next; //前次最小節點的next指向當前min的next,這樣就讓min離開了原連結串列
}
}
if (first != NULL) //迴圈結束得到有序連結串列first
{
tail->next = NULL; //單向連結串列的最後一個節點的next應該指向NULL
}
head = first;
return head;
}
//查詢好友
/* PNode Search(PNode h, char *Name)
{
while (h && strcmp(h->Name,Name) != 0)
{
h = h->next;
}
if (h->next == NULL && strcmp(h->Name,Name) != 0)
{
printf ("Sorry 親,無此好友 \n");
}
return h;
} */
//查詢好友
void Search(PNode head, char *Name)
{
PNode p = head;
PNode q = NULL;
while (p != NULL && (p->next) != NULL)
{
q = p->next;
if (q != NULL && strcmp(q->Name,Name) == 0)
{
printf ("好友資訊: ID: %ld 姓名: %s 手機號碼: %s 家庭地址: %s 公司電話: %s\n", q->ID, q->Name, q->MobNum, q->Addr, q->CpyNum);
return;
}
else if (q->next == NULL && strcmp(q->Name,Name) != 0)
{
printf ("Sorry 親,您的通訊錄沒有該好友!\n");
printf ("請重新輸入主選單指令: 0~4 \n");
}
p = p->next;
}
}
//刪除好友資訊
void Delete_Node(PNode head, char *Name)
{
PNode p = head;
PNode q = NULL;
while (p != NULL && (p->next) != NULL)
{
q = p->next;
if (q != NULL && strcmp(q->Name,Name) == 0)
{
p->next = q->next;
free(q);
printf ("該好友已成功刪除\n");
}
else if (q->next == NULL && strcmp(q->Name,Name) != 0)
{
printf ("Sorry親,您的通訊錄沒有該好友!\n");
printf ("請重新輸入主選單指令: 0~4 \n");
}
p = p->next;
}
}
//列印當前所有結點(好友)
void DisPlayAll(PNode h)
{
if (h == NULL)
{
return;
}
PNode temp = h->next;//連結串列第一個結點指標
while (temp)
{
printf ("ID: %ld 姓名: %s 手機號碼: %s 家庭地址: %s 公司電話: %s\n\n", temp->ID, temp->Name, temp->MobNum, temp->Addr, temp->CpyNum);
temp = temp->next;
}
printf ("\n");
}
// 列印當前建立結點(好友)
void DisPlay(PNode h)
{
if (h == NULL)
{
return;
}
PNode temp = h->next; // 連結串列第一個結點指標
while (temp)
{
if (temp->next == NULL)
{
printf ("\n\t......使用者%s已成功建立......\n", temp->Name);
}
temp = temp->next;
}
printf ("\n");
}
//主選單
int Menu()
{
printf ("************************************************************\n");
printf ("* 歡迎進入通訊錄管理系統! *\n");
printf ("************************************************************\n");
printf ("* 1)新增好友 *\n");
printf ("* 2)列表好友資訊 *\n");
printf ("* 3)搜尋好友 *\n");
printf ("* 4)刪除好友 *\n");
printf ("************************************************************\n");
printf ("*********新增好友: 1 檢視當前好友資訊: 2**************\n");
printf ("*********搜尋好友: 3 刪除好友: 4**************\n");
printf ("******************顯示主選單: 0*****************************\n");
printf ("************************************************************\n\n");
}
//功能選單
int FunMeun()
{
printf ("\n\n");
printf (" * * ***** * * ****** **** 功能選擇: \n");
printf (" * * * * * * * ** \n");
printf (" * * * * * * * ** 顯示主選單: 0\n");
printf (" ****** ***** * * * * ** 新增好友: 1\n");
printf (" * * * * * * * 檢視當前好友資訊: 2\n");
printf (" * * * * * * * ** 搜尋好友: 3\n");
printf (" * * ***** * * ****** ** 刪除好友: 4\n\n");
}
//功能選擇函式
int Select()
{
int choice;
while (1)
{
scanf("%d", &choice);
if (!(choice>=0 && choice<=4))
{
printf ("\n\t輸入錯誤,重選0-4:\n\n");
continue;
}
else
{
break;
}
}
return choice;
}
int main()
{
long ID; //ID號
char Name[20]; //姓名
char MobNum[13]; //手機號碼
char Addr[50]; //地址
char CpyNum[13]; //公司電話
PNode head_node = (PNode)malloc(sizeof(Node)/sizeof(char));
if (head_node == NULL)
{
return ERROR;
}
head_node->next = NULL;
Menu();//顯示主介面
while (1)
{
switch(Select())
{
case 0:
{
Menu();
}break;
case 1://新增好友
{
if (head_node)
{
if (Create_List_Tail(head_node, ID, Name, MobNum, Addr, CpyNum) != OK)
{
return ERROR;
}
}
DisPlay(head_node);//列印當前好友建立資訊
head_node = SelectSort(head_node); //建立完成就進行排序,防止後面程式出錯
FunMeun();
}break;
case 2://顯示好友資訊
{
printf ("*******************當前好友資訊***********************\n");
//head_node = SelectSort(head_node); //顯示好友前先通過ID號對好友資訊進行升序
DisPlayAll(head_node);//顯示所有好友資訊
FunMeun();
}break;
case 3://查詢好友
{
printf ("請輸入你要查詢好友的姓名: \n");
scanf ("%s", Name);
Search(head_node,Name);
FunMeun();
}break;
case 4://刪除好友
{
printf ("請輸入要刪除好友的姓名\n");
scanf ("%s", Name);
Delete_Node(head_node,Name);
FunMeun();
}break;
default:
{
return ERROR;
}
}
}
return 0;
}
File Name: ******
Author: *** Date: 2016-12-08
Description: 用連結串列實現通訊錄功能
Functionlist: Create_List_Tail();//新增好友
SelectSort(); //對好友進行升序排序
Search(); //查詢好友
Delete_Node(); //刪除好友
DisPlayAll(); //顯示所有好友資訊
DisPlay(); //列印當前建立好友
Meun(); //主選單
FunMeun(); //功能選單
main(); //主函式
***********************************************************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OK 0
#define ERROR -1
#define MALLOC_ERROR -2
typedef struct node
{
long ID; //ID號
char Name[20]; //姓名
char MobNum[13]; //手機號碼
char Addr[50]; //地址
char CpyNum[13]; //公司電話
struct node *next; //結點指標
}Node;
typedef Node *PNode; //重新命名結點指標型別
//尾插法建立連結串列(新增好友資訊)
int Create_List_Tail(PNode h, long ID, char *Name, char *MobNum, char *Addr, char *CpyNum)
{
if (h == NULL)
{
return ERROR;
}
PNode node = (PNode)malloc(sizeof(Node)/sizeof(char));
if (node == NULL)
{
return MALLOC_ERROR;
}
printf("建立使用者\n");
printf ("請輸入ID: ");
scanf ("%ld", &node->ID);
printf ("請輸入姓名: ");
scanf ("%s", node->Name);
printf ("請輸入手機號碼: ");
scanf ("%s", node->MobNum);
printf ("請輸入家庭地址: ");
scanf ("%s", node->Addr);
printf ("請輸入公司電話: ");
scanf ("%s", node->CpyNum);
node->next = NULL;
//找到最後一個結點
PNode temp = h;
while (temp->next)
{
temp = temp->next;
}
temp->next = node;
return OK;
}
//對連結串列用選擇排序法進行升序排序(通過ID號)
PNode SelectSort(PNode head)
{
PNode first; //排列後有序鏈的表頭指標
PNode tail; //排列後有序鏈的表尾指標
PNode p_min; //保留鍵值更小的節點的前驅節點的指標
PNode min; //儲存最小節點
PNode p; //當前比較的節點
first = NULL;
while(head != NULL) //在連結串列中找鍵值最小的節點
{
//注意:這裡for語句就是體現選擇排序思想的地方
for (p = head, min = head; p->next != NULL; p = p->next) //迴圈遍歷連結串列中的節點,找出此時最小的節點
{
if ((p->next->ID) < (min->ID)) //找到一個比當前min小的節點
{
p_min = p; //儲存找到節點的前驅節點:顯然p->next的前驅節點是p
min = p->next; //儲存鍵值更小的節點
}
}
//上面for語句結束後,就要做兩件事;一是把它放入有序連結串列中;二是根據相應的條件判斷,安排它離開原來的連結串列
//第一件事
if (first == NULL) //如果有序連結串列目前還是一個空連結串列
{
first = min; //第一次找到鍵值最小的節點
tail = min; //注意:尾指標讓它指向最後的一個節點
}
else //有序連結串列中已經有節點
{
tail->next = min; //把剛找到的最小節點放到最後,即讓尾指標的next指向它
tail = min; //尾指標也要指向它
}
//第二件事
if (min == head) //如果找到的最小節點就是第一個節點
{
head = head->next; //顯然讓head指向原head->next,即第二個節點,就OK
}
else //如果不是第一個節點
{
p_min->next = min->next; //前次最小節點的next指向當前min的next,這樣就讓min離開了原連結串列
}
}
if (first != NULL) //迴圈結束得到有序連結串列first
{
tail->next = NULL; //單向連結串列的最後一個節點的next應該指向NULL
}
head = first;
return head;
}
//查詢好友
/* PNode Search(PNode h, char *Name)
{
while (h && strcmp(h->Name,Name) != 0)
{
h = h->next;
}
if (h->next == NULL && strcmp(h->Name,Name) != 0)
{
printf ("Sorry 親,無此好友 \n");
}
return h;
} */
//查詢好友
void Search(PNode head, char *Name)
{
PNode p = head;
PNode q = NULL;
while (p != NULL && (p->next) != NULL)
{
q = p->next;
if (q != NULL && strcmp(q->Name,Name) == 0)
{
printf ("好友資訊: ID: %ld 姓名: %s 手機號碼: %s 家庭地址: %s 公司電話: %s\n", q->ID, q->Name, q->MobNum, q->Addr, q->CpyNum);
return;
}
else if (q->next == NULL && strcmp(q->Name,Name) != 0)
{
printf ("Sorry 親,您的通訊錄沒有該好友!\n");
printf ("請重新輸入主選單指令: 0~4 \n");
}
p = p->next;
}
}
//刪除好友資訊
void Delete_Node(PNode head, char *Name)
{
PNode p = head;
PNode q = NULL;
while (p != NULL && (p->next) != NULL)
{
q = p->next;
if (q != NULL && strcmp(q->Name,Name) == 0)
{
p->next = q->next;
free(q);
printf ("該好友已成功刪除\n");
}
else if (q->next == NULL && strcmp(q->Name,Name) != 0)
{
printf ("Sorry親,您的通訊錄沒有該好友!\n");
printf ("請重新輸入主選單指令: 0~4 \n");
}
p = p->next;
}
}
//列印當前所有結點(好友)
void DisPlayAll(PNode h)
{
if (h == NULL)
{
return;
}
PNode temp = h->next;//連結串列第一個結點指標
while (temp)
{
printf ("ID: %ld 姓名: %s 手機號碼: %s 家庭地址: %s 公司電話: %s\n\n", temp->ID, temp->Name, temp->MobNum, temp->Addr, temp->CpyNum);
temp = temp->next;
}
printf ("\n");
}
// 列印當前建立結點(好友)
void DisPlay(PNode h)
{
if (h == NULL)
{
return;
}
PNode temp = h->next; // 連結串列第一個結點指標
while (temp)
{
if (temp->next == NULL)
{
printf ("\n\t......使用者%s已成功建立......\n", temp->Name);
}
temp = temp->next;
}
printf ("\n");
}
//主選單
int Menu()
{
printf ("************************************************************\n");
printf ("* 歡迎進入通訊錄管理系統! *\n");
printf ("************************************************************\n");
printf ("* 1)新增好友 *\n");
printf ("* 2)列表好友資訊 *\n");
printf ("* 3)搜尋好友 *\n");
printf ("* 4)刪除好友 *\n");
printf ("************************************************************\n");
printf ("*********新增好友: 1 檢視當前好友資訊: 2**************\n");
printf ("*********搜尋好友: 3 刪除好友: 4**************\n");
printf ("******************顯示主選單: 0*****************************\n");
printf ("************************************************************\n\n");
}
//功能選單
int FunMeun()
{
printf ("\n\n");
printf (" * * ***** * * ****** **** 功能選擇: \n");
printf (" * * * * * * * ** \n");
printf (" * * * * * * * ** 顯示主選單: 0\n");
printf (" ****** ***** * * * * ** 新增好友: 1\n");
printf (" * * * * * * * 檢視當前好友資訊: 2\n");
printf (" * * * * * * * ** 搜尋好友: 3\n");
printf (" * * ***** * * ****** ** 刪除好友: 4\n\n");
}
//功能選擇函式
int Select()
{
int choice;
while (1)
{
scanf("%d", &choice);
if (!(choice>=0 && choice<=4))
{
printf ("\n\t輸入錯誤,重選0-4:\n\n");
continue;
}
else
{
break;
}
}
return choice;
}
int main()
{
long ID; //ID號
char Name[20]; //姓名
char MobNum[13]; //手機號碼
char Addr[50]; //地址
char CpyNum[13]; //公司電話
PNode head_node = (PNode)malloc(sizeof(Node)/sizeof(char));
if (head_node == NULL)
{
return ERROR;
}
head_node->next = NULL;
Menu();//顯示主介面
while (1)
{
switch(Select())
{
case 0:
{
Menu();
}break;
case 1://新增好友
{
if (head_node)
{
if (Create_List_Tail(head_node, ID, Name, MobNum, Addr, CpyNum) != OK)
{
return ERROR;
}
}
DisPlay(head_node);//列印當前好友建立資訊
head_node = SelectSort(head_node); //建立完成就進行排序,防止後面程式出錯
FunMeun();
}break;
case 2://顯示好友資訊
{
printf ("*******************當前好友資訊***********************\n");
//head_node = SelectSort(head_node); //顯示好友前先通過ID號對好友資訊進行升序
DisPlayAll(head_node);//顯示所有好友資訊
FunMeun();
}break;
case 3://查詢好友
{
printf ("請輸入你要查詢好友的姓名: \n");
scanf ("%s", Name);
Search(head_node,Name);
FunMeun();
}break;
case 4://刪除好友
{
printf ("請輸入要刪除好友的姓名\n");
scanf ("%s", Name);
Delete_Node(head_node,Name);
FunMeun();
}break;
default:
{
return ERROR;
}
}
}
return 0;
}