通讯录管理系统(C/C++)

问题描述

设计与实现一个通讯录管理系统,实现按姓名、电话号、QQ 号查找。

功能要求

  1. 要求能够管理通讯录,即具有通讯录的建立、增、删、改记录功能;
  2. 要求实现在指定通讯录中按姓名、电话号、QQ 号查找功能。

系统描述

通讯录管理系统逻辑图

信息结构

系统信息结构

通讯录查找子系统

二分查找(QQ号)

QQ号查找主要思想

先给QQ号排序

void sort_QQ(SqList &p)//qq排序
{
    int i,j,w;
    ElemType *temp;
    for(i=0; i<n; i++)
        for(j=i+1; j<n; j++)
        {
            w=i;
            if(strcmp(p.data[w]->QQnum,p.data[j]->QQnum)>0)//若data[w]字符串大于data[j]
                w=j;
            if(i!=w)
            {
                temp=p.data[i];
                p.data[i]=p.data[j];
                p.data[j]=temp;
            }
        }
}

然后再用二分法查找

int Search_QQ(SqList p,char *key)//二分法查找qq号
{
    int low=0,high=p.length-1,mid;
    while(low<=high)
    {
        mid=(low+high)/2;
        if(strcmp(key,p.data[mid]->QQnum)==0)
            return mid;
        else if(strcmp(key,p.data[mid]->QQnum)<0)
            high=mid-1;
        else
            low=mid+1;
    }
    return -1;
}

二叉排序树查找手机号

手机号查找主要思想

先新建一个二叉排序树,一个一个插入节点

void InsertBST(BSTree &T,ElemType *e)//二叉排序树插入节点
{
    BSTree S;
    if(!T)
    {
        S=new BSTNode;
        S->data=e;
        S->lchild=S->rchild=NULL;
        T=S;
    }
    else if(strcmp(e->phonenum,T->data->phonenum)<0)
        InsertBST(T->lchild,e);
    else if(strcmp(e->phonenum,T->data->phonenum)>0)
        InsertBST(T->rchild,e);
}
void CreatBST(BSTree &T,Linklist head)//新建二叉排序树
{
    T=NULL;
    Linklist p=head->next;
    ElemType *e=&p->data;
    while(p)
    {
        InsertBST(T,e);
        p=p->next;
        e=&p->data;
    }
}

二叉排序树的递归搜索

BSTree Search_BST(BSTree T,KeyType key)//二叉排序树递归搜索
{
    if((!T)||!strcmp(key,T->data->phonenum))
        return T;
    else if(strcmp(key,T->data->phonenum)<0)
        return Search_BST(T->lchild,key);
    else
        return Search_BST(T->rchild,key);
}

散列表查找姓名

先创建一个散列表

HashLL Create_Hash(Linklist head)
{
    HashLL H=new HashLN[300],q;
    Linklist p=head->next;
    int i;
    for(i=0; i<171; i++)
    {
        H[i].data=NULL;
        H[i].next=NULL;
    }
    while(p)
    {
        i=p->data.name[0]-'0'+p->data.name[1]-'0'+p->data.name[2]-'0'-150;//hash---处理姓名前三位
        if(H[i].data!=NULL)
        {
            q=new HashLN;
            q->data=&(p->data);
            q->next=H[i].next;
            H[i].next=q;
        }
        else
            H[i].data=&(p->data);
        p=p->next;
    }
    return H;
}
然后以姓名为关键字构建散列函数进行查找

```c
ElemType* Search_name(HashLL H,char *name)
{
    int i;
    HashLL p,N=new HashLN;
    ElemType *e;
    i=name[0]-'0'+name[1]-'0'+name[2]-'0'-150;//hash---处理姓名前三位
    N->data=NULL;
    if(H[i].data==NULL)
    {
        cout<<"查无此人!"<<endl;
        return N->data;
    }
    if(strcmp(H[i].data->name,name)==0)
        return H[i].data;
    else
    {
        p=H[i].next;
        while(p)
        {
            if(strcmp(p->data->name,name)==0)
                return p->data;
            p=p->next;
        }
        cout<<"查无此人!"<<endl;
        return N->data;
    }
}

通讯录编辑子系统

这部分用文件读写就可实现,主要就是文件的增删改查。
这部分就不加提示了。
如果有问题可以评论区问我。

实验源码

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<iomanip>
#define MAXSIZE 1000
using namespace std;
typedef char *KeyType;
/*---------------------------------------信息结构--------------------------------------*/
typedef struct
{
    char name[20];
    char phonenum[20];
    char QQnum[20];
    char company[50];
    char address[100];
} ElemType,*Phone;
/*---------------------------------------信息结构--------------------------------------*/
typedef struct LNode
{
    ElemType data;
    struct LNode *next;
} LNode,*Linklist;
typedef struct
{
    Phone *data;
    int length;
} SqList;

/*----------------------------树结构-----------------------------------*/
typedef struct BSTNode
{
    ElemType *data;
    struct BSTNode *lchild,*rchild;
} BSTNode,*BSTree;
/*----------------------------树结构-----------------------------------*/
/*---------------------------hash表----------------------------------*/
typedef struct HashLN
{
    ElemType *data;
    struct HashLN *next;
} HashLN,*HashLL;
/*---------------------------hash表----------------------------------*/
int n;
int m_num(int n,char *file)//计算文件中信息个数
{
    FILE *fp;
    long length;//计算文件字节数
    if((fp = fopen(file,"rb")) != NULL)
        fp = fopen(file,"rb");
    fseek(fp,0L,2);
    length = ftell(fp);
    fclose(fp);
    return length/n;
}
void FILEREAD(char *file,Linklist &head)//循环按块读取
{
    FILE *fp;
    Linklist r,p,q;
    head=new LNode;
    head->next=NULL;
    r=head;
    if((fp=fopen(file,"rb"))==NULL)
        return;
    while(!feof(fp))
    {
        q=r;
        p=new LNode;
        fread(&p->data,sizeof(ElemType),1,fp);
        r->next=p;
        r=p;
    }
    q->next=NULL;
    delete p;
    fclose(fp);
}
void printelem(ElemType e)
{
    //cout<<"  姓名       电话号       QQ号       单位        住址"<<endl;
    cout<<"|  "<<setw(20)<<e.name;
    cout<<setw(20)<<e.phonenum;
    cout<<setw(20)<<e.QQnum;
    cout<<setw(20)<<e.company;
    cout<<setw(20)<<e.address<<"  |";
    cout<<endl;
}
SqList Link_Sq(Linklist head)//建立链表
{
    SqList ph;
    ph.data=new Phone[n];
    Linklist p=head->next;
    int i=0;
    while(p)
    {
        ph.data[i]=&p->data;
        i++;
        p=p->next;
    }
    ph.length=n;
    return ph;
}
void sort_QQ(SqList &p)//qq排序
{
    int i,j,w;
    ElemType *temp;
    for(i=0; i<n; i++)
        for(j=i+1; j<n; j++)
        {
            w=i;
            if(strcmp(p.data[w]->QQnum,p.data[j]->QQnum)>0)//若data[w]字符串大于data[j]
                w=j;
            if(i!=w)
            {
                temp=p.data[i];
                p.data[i]=p.data[j];
                p.data[j]=temp;
            }
        }
}
void InitLink(Linklist &head)//初始化
{
    head=new LNode;
    head->next=NULL;
}
void ADD(Linklist &head,char *file)//插入信息
{
    char flag='1';
    Linklist r=head,p;
    while(r->next)
        r=r->next;
    while(flag!='0')
    {
        p=new LNode;
        cout<<"请输入姓名  : ";
        cin>>p->data.name;
        cout<<"请输入手机号: ";
        cin>>p->data.phonenum;
        cout<<"请输入QQ号  : ";
        cin>>p->data.QQnum;
        cout<<"请输入单位  : ";
        cin>>p->data.company;
        cout<<"请输入地址  : ";
        cin>>p->data.address;
        r->next=p;
        r=p;
        cout<<"停止请按0,否则请按回车。"<<endl;
        getchar();
        flag=getchar();
    }
    p->next=NULL;
}
void Traverse_Link(Linklist head)//初始界面
{
    cout<<n<<endl;
    Linklist p=head->next;
    cout<<" ________________________________________________________________________________________________________"<<endl;
    cout<<"|                                                                                                        |"<<endl;
    cout<<"|           姓名                   电话号                 QQ号                 单位                住址  |"<<endl;
    while(p)
    {
        printelem(p->data);
        p=p->next;
    }
    cout<<"|________________________________________________________________________________________________________|"<<endl;
}
void WRITEFILE_LINK(Linklist head,char *file)//按块写入文件
{
    FILE *fp=fopen(file,"wb");
    Linklist p=head->next;
    while(p)
    {
        fwrite(&p->data,sizeof(ElemType),1,fp);
        p=p->next;
    }
    fclose(fp);
}
void Correct(ElemType *e)
{
    int n,flag=1;
    char c[20];
    while(flag)
    {
        cout<<"*****请选择******"<<endl;
        cout<<"*   1,姓名     *"<<endl;
        cout<<"*   2,电话号   *"<<endl;
        cout<<"*   3,QQ号     *"<<endl;
        cout<<"*   4,单位     *"<<endl;
        cout<<"*   5,地址     *"<<endl;
        cout<<"*   6,退出修改 *"<<endl;
        cout<<"*****************"<<endl;
        cin>>n;
        switch(n)
        {
        case 1:
            cout<<"请输入:";
            cin>>c;
            strcpy(e->name,c);
            break;
        case 2:
            cout<<"请输入:";
            cin>>c;
            strcpy(e->phonenum,c);
            break;
        case 3:
            cout<<"请输入:";
            cin>>c;
            strcpy(e->QQnum,c);
            break;
        case 4:
            cout<<"请输入:";
            cin>>c;
            strcpy(e->company,c);
            break;
        case 5:
            cout<<"请输入:";
            cin>>c;
            strcpy(e->address,c);
            break;
        case 6:
            flag=0;
        }
    }
}
void Delete(Linklist head,char *name)//删除指定信息
{
    Linklist p,q=head;
    p=head->next;
    while(p&&strcmp(p->data.name,name)!=0)//姓名不相等,以及查找没有到尾
    {
        q=p;
        p=p->next;
    }
    if(p)
    {
        q->next=p->next;
        delete p;
        cout<<"删除成功!"<<endl;
    }
    else
        cout<<"查无此人!"<<endl;
}
int Search_QQ(SqList p,char *key)//二分法查找qq号
{
    int low=0,high=p.length-1,mid;
    while(low<=high)
    {
        mid=(low+high)/2;
        if(strcmp(key,p.data[mid]->QQnum)==0)
            return mid;
        else if(strcmp(key,p.data[mid]->QQnum)<0)
            high=mid-1;
        else
            low=mid+1;
    }
    return -1;
}
BSTree Search_BST(BSTree T,KeyType key)//二叉排序树递归搜索
{
    if((!T)||!strcmp(key,T->data->phonenum))
        return T;
    else if(strcmp(key,T->data->phonenum)<0)
        return Search_BST(T->lchild,key);
    else
        return Search_BST(T->rchild,key);
}
void InsertBST(BSTree &T,ElemType *e)//二叉排序树插入
{
    BSTree S;
    if(!T)
    {
        S=new BSTNode;
        S->data=e;
        S->lchild=S->rchild=NULL;
        T=S;
    }
    else if(strcmp(e->phonenum,T->data->phonenum)<0)
        InsertBST(T->lchild,e);
    else if(strcmp(e->phonenum,T->data->phonenum)>0)
        InsertBST(T->rchild,e);
}
void CreatBST(BSTree &T,Linklist head)//新建二叉排序树
{
    T=NULL;
    Linklist p=head->next;
    ElemType *e=&p->data;
    while(p)
    {
        InsertBST(T,e);
        p=p->next;
        e=&p->data;
    }
}
HashLL Create_Hash(Linklist head)
{
    HashLL H=new HashLN[300],q;
    Linklist p=head->next;
    int i;
    for(i=0; i<171; i++)
    {
        H[i].data=NULL;
        H[i].next=NULL;
    }
    while(p)
    {
        i=p->data.name[0]-'0'+p->data.name[1]-'0'+p->data.name[2]-'0'-150;//hash---处理姓名前三位
        if(H[i].data!=NULL)
        {
            q=new HashLN;
            q->data=&(p->data);
            q->next=H[i].next;
            H[i].next=q;
        }
        else
            H[i].data=&(p->data);
        p=p->next;
    }
    return H;
}
ElemType* Search_name(HashLL H,char *name)
{
    int i;
    HashLL p,N=new HashLN;
    ElemType *e;
    i=name[0]-'0'+name[1]-'0'+name[2]-'0'-150;//hash---处理姓名前三位
    N->data=NULL;
    if(H[i].data==NULL)
    {
        cout<<"查无此人!"<<endl;
        return N->data;
    }
    if(strcmp(H[i].data->name,name)==0)
        return H[i].data;
    else
    {
        p=H[i].next;
        while(p)
        {
            if(strcmp(p->data->name,name)==0)
                return p->data;
            p=p->next;
        }
        cout<<"查无此人!"<<endl;
        return N->data;
    }
}
void Change()
{
    int a,flag=1;
    Linklist head;
    char file[20]="通讯录.txt",name[20],c='1';
    FILEREAD(file,head);
    ElemType *w;
    HashLL H=Create_Hash(head);
    while(flag)
    {
        cout<<" ____________________________________ "<<endl;
        cout<<"|                                    |"<<endl;
        cout<<"|           通 讯 录 编 辑           |"<<endl;
        cout<<"|                                    |"<<endl;
        cout<<"|           1.建立通讯录             |"<<endl;
        cout<<"|           2.增加记录               |"<<endl;
        cout<<"|           3.修改记录               |"<<endl;
        cout<<"|           4.删除记录               |"<<endl;
        cout<<"|           5.查看通讯录             |"<<endl;
        cout<<"|           6.返回主菜单             |"<<endl;
        cout<<"|____________________________________|"<<endl;
        cin>>a;
        switch(a)
        {
        case 1:
            InitLink(head);
            ADD(head,file);
            break;
        case 2:
            ADD(head,file);
            break;
        case 3:
            while(c!='0')
            {
                cout<<"请输入姓名:";
                cin>>name;
                w=Search_name(H,name);
                printelem(*w);
                Correct(w);
                cout<<"是否继续(0/1)"<<endl;
                getchar();
                c=getchar();
            }
            c='1';
            break;
        case 4:
            while(c!='0')
            {
                cout<<"请输入姓名:";
                cin>>name;
                Delete(head,name);
                cout<<"是否继续(0/1)"<<endl;
                getchar();
                c=getchar();
            }
            c='1';
            break;
        case 5:
            Traverse_Link(head);
            break;
        case 6:
            WRITEFILE_LINK(head,file);
            flag=0;
            break;
        }
    }
}
void Search()
{
    int a,flag=1,x;
    Linklist head;
    ElemType *e;
    char phonenum[20];
    char QQ[20],name[20];
    char file[20]="通讯录.txt";
    FILEREAD(file,head);
    SqList p=Link_Sq(head);
    BSTree T,temp;
    HashLL H=Create_Hash(head);
    while(flag)
    {
        cout<<" ____________________________________ "<<endl;
        cout<<"|                                    |"<<endl;
        cout<<"|                                    |"<<endl;
        cout<<"|           通 讯 录 查 找           |"<<endl;
        cout<<"|                                    |"<<endl;
        cout<<"|          1.按姓名查找              |"<<endl;
        cout<<"|          2.按qq号查找              |"<<endl;
        cout<<"|          3.按电话号查找            |"<<endl;
        cout<<"|          4.返回主菜单              |"<<endl;
        cout<<"|____________________________________|"<<endl;
        cin>>a;
        switch(a)
        {
        case 1:
            cout<<"请输入姓名:";
            cin>>name;
            e=Search_name(H,name);
            if(e!=NULL)printelem(*e);
            break;
        case 2:
            cout<<"请输入QQ:";
            cin>>QQ;
            sort_QQ(p);
            x=Search_QQ(p,QQ);
            if(x!=-1)
                printelem(*p.data[x]);
            else
                cout<<"没找到!"<<endl;
            break;
        case 3:
            cout<<"请输入电话号:";
            cin>>phonenum;
            CreatBST(T,head);
            temp=Search_BST(T,phonenum);
            if(temp)
                printelem(*temp->data);
            else
                cout<<"查无此人!"<<endl;
            break;
        case 4:
            flag=0;
        }
    }
}
void menu()
{
    char file[20]="通讯录.txt";
    n=m_num(sizeof(ElemType),file);
    int a,flag=1;
    while(flag)
    {
        cout<<" ____________________________________ "<<endl;
        cout<<"|                                    |"<<endl;
        cout<<"|          通 讯 录 管 理            |"<<endl;
        cout<<"|                                    |"<<endl;
        cout<<"|          1.通讯录编辑              |"<<endl;
        cout<<"|          2.通讯录查找              |"<<endl;
        cout<<"|          3.返回主菜单              |"<<endl;
        cout<<"|____________________________________|"<<endl;
        cin>>a;
        switch(a)
        {
        case 1:
            Change();
            break;
        case 2:
            Search();
            break;
        case 3:
            flag=0;
            break;
        }
    }
}
int main()
{
    menu();
    return 0;
}

xdjmm 觉得文章还可以的话 点个赞呗~

在这里插入图片描述

  • 12
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二琳爱吃肉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值