1. 程式人生 > >用單鏈表實現通訊錄

用單鏈表實現通訊錄

/*********************************************************************************************************************************
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;
}