单链表+学生信息管理系统

什么也不说了,先看代码吧,写了好久,虽然不怎么涉及算法,当时涉及到了指针,我写下来的感觉就是,全是指针呀,服了。

代码:

/*
总结:指针指向无效的地址或者 指针是NULL但是却对其访问
是一个经常会出现的错误。
*/
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
const char *guangzhou="山东";
int n = 0;
FILE *filep=NULL;
int listSize = 0;
//设传入的T是头节点的引用,不含数据
struct XscjList
{
    char NO[15];
    char Name[20];
    char MTel[20];
    char Email[20];
    char BornAddr[20];
    float Ascore;
    float Bscore;
    float Cscore;
    struct XscjList *next;
};
typedef XscjList* XscjLink;
typedef long long ll;
void Sort(XscjList& T);
int Count(XscjList& T);
void Build(XscjList& T);
void ReverseN(XscjList& T);
void MoveK(XscjList& T,int k);
void Merge(XscjList &T1, XscjList &T2);
void Update(XscjList& T, char *Name, float ScoreA);
void OutPut(XscjList& T);
void Inset(XscjList& T, const char *Name, const char *No);

void Build(XscjList& T)
{
    if (filep==NULL)
        filep = fopen("1.txt", "r+");
    int n = 0;
    XscjLink p = &T, q = NULL;
    //freopen("1.txt", "r", stdin);
    fscanf(filep,"%d", &n);
    cout<<"n="<<n<<endl;
    while(n--)
    {
        q = (XscjLink)malloc(sizeof(XscjList));
        fscanf(filep,"%s %s %s %s %s", q->NO, q->Name, q->MTel, q->Email, q->BornAddr);
        fscanf(filep,"%f %f", &(q->Ascore), &(q->Bscore));
        p->next = q;
        p = p->next;
        p->next=NULL;
    }
//    OutPut(T);
//    cout<<"----------------------------------"<<endl<<endl;

}
void Update(XscjList& T, char *Name, float ScoreA)
{
    XscjLink p = T.next;
    while(p)
    {
        if(strcmp(p->Name, Name) == 0)
        {
            p->Ascore = ScoreA;
            break;
        }
        else
            p = p->next;
    }
    if(p == NULL) printf("Update fail!");
}
void OutPut(XscjList& T)
{
    XscjLink p = T.next;
    while(p)
    {
        printf("%s  %-8s  %s  %s  %6s  %3.2f  %3.2f\n",
               p->NO, p->Name, p->MTel, p->Email, p->BornAddr, p->Ascore, p->Bscore);
        p = p->next;
    }
}
void Inset(XscjList& T, const char *Name, const char *No)
{
    //应该重新新建一个链表,并且返回去将T.next修改了就可以了
    //循环2次
    XscjList InsetHead = T;
    XscjLink p = &T, q = &InsetHead;
    while(p->next)
    {
        int flag = strcmp(p->next->NO, No);
        if(flag <=0)
        {
            q->next = p->next;
            p->next = p->next->next;
            q = q->next;
            continue;
        }
        p = p->next;
    }
    q = q->next = (XscjLink)malloc(sizeof(XscjList));
    strcpy(q->Name, Name);
    strcpy(q->NO, No);
    q->next=T.next;
    T=InsetHead;
}
int Count(XscjList& T)
{
    int cnt =0;
    XscjLink p = &T;
    while (p->next)
    {
        if (!strcmp(p->next->BornAddr,guangzhou))cnt++;
        p=p->next;
    }
    return cnt;
}
//实现函数void Sort(XscjLink T)
//将该学生按照B分成绩进行非递减排序;
//succeed
void Sort(XscjList& T)
{
    T.Bscore=-1;
    XscjLink base=T.next,p=base->next,t=NULL,q=NULL;
    base->next=NULL;

    while (p!=NULL)
    {
        //if (!(t=p->next)) break;
        t=p->next;
        if (p->Bscore<=base->Bscore)
        {
            q=&T;

            while (true)
            {
                if (q->Bscore < p->Bscore
                  &&q->next->Bscore >=p->Bscore)
                  {
                      p->next=q->next;
                      q->next=p;
                      break;
                  }
                q=q->next;
            }
        }
        else
        {
            base->next=p;
            base=p;
            base->next=NULL;
        }

        p=t;
    }
}
/*
将两个按B分成绩非递减排序的学生成绩单合并为一个
按B分成绩非递增排序的通讯录,B分成绩相同且学号
相同的成绩记录在结果中只保留一个;
要求算法的时间复杂度不超过两个链表的长度之和O(m+n);
*/
//texting
void Merge(XscjList &T1, XscjList &T2)
{
    //将T1和和T2链表合成到T1中;
    Sort(T1);Sort(T2);
    ReverseN(T1);ReverseN(T2);
    OutPut(T1);
    cout<<"-----------------------------"<<endl;
    OutPut(T2);
    cout<<"-----------------------------"<<endl;
    XscjLink p=&T1,q=T2.next;

    T1.Bscore=10.0;//10.0 is bigger than any Bscore;
    while(p!=NULL && q!=NULL)
    {
        if (strcmp(p->NO,q->NO)==0)
        {
            cout<<"p->NO="<<p->NO<<endl;
            cout<<"q->NO="<<q->NO<<endl;
            q=T2.next=q->next;
            continue;
        }

        if (p->Bscore > q->Bscore &&
            (p->next==NULL || p->next->Bscore <= q->Bscore))
            {
                T2.next=q->next;
                q->next=p->next;
                p->next=q;
                p=p->next;
                q=T2.next;

//                OutPut(T1);
//                cout<<"-----------------------------"<<endl;
            }
        else
        {
            p=p->next;
        }
    }

}
/*
将学生成绩链表的正中间位置结点之后的全部结点倒置,
注意:严禁采用先计算链表长度n再除以2(即n/2)的
方法;要求算法的时间复杂度不超过个链表的长度O(n);
*/
//text succeed
void ReverseN(XscjList& T)
{
    if (T.next==NULL) return ;

    XscjLink p=T.next,q=p->next;
    p->next=NULL;

    while (q!=NULL)
    {
        p=T.next;
        T.next=q;
        q=q->next;
        T.next->next=p;
    }
}
/*
将学生成绩链表中倒数第k个结点之后的所有结点移到
头结点后面(保持结点间的先后顺序),注意:
严禁采用先计算链表长度n再减k(即n-k)的方法;
要求算法的时间复杂度不超过个链表的长度O(n);
*/
//success
void MoveK(XscjList& T,int k)
{
    int i=0;
	XscjLink p=&T,q=p;
	while (q->next!=NULL)
    {
        q=q->next;
        if (i>=k)
            p=p->next;
        i++;
    }
    q->next=T.next;
    T.next=p->next;
    p->next=NULL;
}
//texting
int main()
{
    XscjList AI1,AI2;
    Build(AI1);
//    Sort(AI1);
//    ReverseN(AI1);
    Build(AI2);
    Merge(AI1,AI2);
    OutPut(AI1);
    cout<<"----------------------------------"<<endl<<endl;
    OutPut(AI2);
    cout<<"----------------------------------"<<endl<<endl;
//    Sort(AI1);
//     OutPut(AI1);
//    cout<<"----------------------------------"<<endl<<endl;
//    //MoveK(AI,3);
//    Sort(AI);
//    //ReverseN(AI);
//    OutPut(AI);

    return 0;
}


  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值