c-项目(公交调度子系统)

项目功能:

a.可实时浏览目前处于运行中的所用公交线路的信息;

b.可及时记录并做存储调度后的公交线路;

c.可删除进站后的公交运行记录,以便进行新的调度;

d,可按照不同信息进行特定排序查询,以便找到最关心的行车记录。

e.可将调度后的公交信息按照不同的优先级进行记录;

f.可根据指定车次,快速查询该车次目前所有的信息;

g.可及时修改指定运行中车次的其他信息(比如: 运行站点的改变)

项目流程:

应用到的知识点:

1.数据结构 (单向链表)

2.文件操作 (数据存储和加载)

3.基础算法 (选择排序)

4.链表原理和基本操作 链表的头插法,尾插法,链表节点的删除 和查询及数据修改。

5.动态内存申请及二级指针 二级指针实现链表外排序。

file.h

cpp 复制代码
#ifndef __FILE_H
#define __FILE_H

#include "slist.h"

int load(NODE** head);
int save(const NODE* head);


#endif

file.c

cpp 复制代码
#include "file.h"
#include <stdio.h>

// 文件的读取
int load(NODE** head)
{
    FILE *fp = fopen("bus.dat","r");
    if(!fp)
        return -1;
    DATA  data = {0};

    while(fread(&data,sizeof(DATA),1,fp) == 1)
    {
         slist_addTail(head,data);
    }
    fclose(fp);
    return 0;
}

// 文件的写入
int save(const NODE* head)
{
    if(!head)
       return -1;
    FILE *fp = fopen("bus.dat","w");
    if(!fp)
        return -1;
    NODE* p = (NODE*)head;   
    while(p)
    {
         fwrite(&(p -> data),sizeof(DATA),1,fp);
         p  = p -> next;
    }
    fclose(fp);

    return 0;
}
cpp 复制代码
#ifndef __MENU_H
#define __MENU_H

#include "slist.h"

void  welcome();
int mainmenu(NODE**);
int browsemenu(NODE**);
int addmenu(NODE**);
int deletemenu(NODE**);

#endif
cpp 复制代码
#include "menu.h"
#include "function.h"
#include <stdio.h>


void welcome(void)
{
   puts("**********************");
   puts("***               ****");
   puts("***               ****");
   puts("***公交调度子系统 ****");
   puts("***               ****");
   puts("***               ****");
   puts("*** ver1.00.00    ****");
   puts("***               ****");
   puts("***               ****");
   puts("**********************");
   puts("***  按任意键继续 ****");
   
   getchar(); 
}

int mainmenu(NODE** head)
{
   puts("**********************");
   puts("*** 1.显示记录    ****");
   puts("*** 2.添加记录    ****");
   puts("*** 3.删除记录    ****");
   puts("*** 4.查询记录    ****");
   puts("*** 5.修改记录    ****");
   puts("*** 0.退出        ****");
   puts("**********************");
   
   puts("\n");

   while(getchar() != '\n') ;

   char  sel = 0;
   printf("\t请选择:");
   scanf("%c",&sel);

   switch(sel)
   {
       case    '0':
               return 0;
       case    '1':
               while(browsemenu(head)) ;
               break; 
       case    '2':
               while(addmenu(head)) ;
               break; 
       case    '3':
               while(deletemenu(head)) ;
               break; 
       case    '4':
               //query(*head);
               break; 
       case    '5':
               break; 
       default :
               puts("功能开发中...");
   }
   return  sel != 0;
}

int browsemenu(NODE** head)
{
   puts("**************************");
   puts("*** 1.运行车次排序    ****");
   puts("*** 2.按照终点站排序  ****");
   puts("*** 3.按照里程排序    ****");
   puts("*** 4.不排序显示      ****");
   puts("*** 0.返回上一级      ****");
   puts("**************************");
   
   puts("\n");

   int  sel = -1;
   printf("\t请选择:");
   scanf("%d",&sel);

   switch(sel)
   {
       case    0:
               return 0;
       case    1:
       case    2:
       case    3:
               Sort(*head,sel);
               break;
       case    4:
               slist_showAll(*head);
               break;
      default :
               puts("功能开发中...");
   }
   return  sel;   
}

int addmenu(NODE** head)
{
   puts("**************************");
   puts("***      1.头插       ****");
   puts("***      2.尾插       ****");
   puts("***                   ****");
   puts("***    0.返回上一级   ****");
   puts("**************************");

   puts("\n");

   int  sel = -1;
   printf("\t请选择:");
   scanf("%d",&sel);

   switch (sel)
   {
       case  0:
             return 0;
       case  1:
       case  2:
             addrecord(head,sel);
             break;
       default:
             puts("功能开发中,敬请期待...");
   } 
   return sel;
}

int deletemenu(NODE** head)
{
   puts("**************************");
   puts("***    1.按车次删除   ****");
   puts("***    2.按站点删除   ****");
   puts("***                   ****");
   puts("***    0.返回上一级   ****");
   puts("**************************");

   puts("\n");

   int  sel = -1;
   printf("\t请选择:");
   scanf("%d",&sel);
   
   switch (sel)
   {
       case  0:
             return 0;
       case  1:
       case  2:
             slist_showAll(*head);
             deleterecord(head,sel);
             break;
       default:
             puts("功能开发中,敬请期待...");
   }
   return sel;
}

slist.h

cpp 复制代码
#ifndef __SLIST_H
#define __SLIST_H

struct Bus
{
    int   line;
    char  start[20];
    char  stop[20];
    char  current[20];
    float km; 
};


typedef  struct Bus  DATA; 

typedef struct node
{
    DATA          data;
    struct node  *next;
}NODE;

int slist_create(NODE**,DATA);
int slist_addHead(NODE** head,DATA data);
int slist_addTail(NODE** head,DATA data);
int slist_insert(NODE** head,DATA pos,DATA data);

NODE* slist_find(const NODE* head,DATA data);
int slist_update(const NODE* head,DATA old,DATA newdata);

void slist_showAll(const NODE* head);
int slist_delete(NODE** head,DATA data);
void slist_destroy(NODE** head);

#endif

slist.c

cpp 复制代码
#include "slist.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/*
@function:   int slist_create(NODE** head,DATA data);
@berif:      创建单项链表
@argument:   head: 指向头指针变量的地址,用来接收首节点地址
             data: 存储在节点中的数据
@return :    成功返回 0
             失败返回 -1
*/
int slist_create(NODE** head,DATA data)
{
    NODE* p  = (NODE*)malloc(sizeof(NODE));
    if(!p)
    {
         return -1;
    }
    p -> data = data;
    p -> next = NULL;

    *head = p;
    return 0;
}

/*
@function:   int slist_addHead(NODE** head,DATA data);
@berif:      向链表头部插入一个节点数据
@argument:   head: 指向头指针变量的地址,用来接收首节点地址
             data: 存储在新节点中的数据
@return :    成功返回 0
             失败返回 -1
*/

int slist_addHead(NODE** head,DATA data)
{
    NODE* p = (NODE*)malloc(sizeof(NODE));
    if(!p)
    {
      return -1;
    }
    p -> data = data;
    p -> next = *head;
    *head     = p;

    return 0;   
}

/*
@function:   int slist_addTail(NODE** head,DATA data);
@berif:      向链表尾部插入一个节点数据
@argument:   head: 指向头指针变量的地址,用来接收首节点地址
             data: 存储在新节点中的数据
@return :    成功返回 0
             失败返回 -1
*/

int slist_addTail(NODE** head,DATA data)
{
    NODE * pNew = (NODE*)malloc(sizeof(NODE));
    if(!pNew)
    {
        return -1;
    }
    pNew -> data = data;
    pNew -> next = NULL;

    NODE* p = *head, *q = NULL;

    if(!p)
    {
        *head = pNew;
        return 0;    
    }
    while(p)
    {
        q  = p;
        p  = p -> next;
    }
    q -> next = pNew;
    
    return 0;
}

/*
@function:   int slist_insert(NODE** head,DATA pos ,DATA data);
@berif:      向链表节点值为pos的位置插入一个节点数据data
@argument:   head: 指向头指针变量的地址
             pos:  插入节点位置的节点数据
             data: 存储在新节点中的数据
@return :    成功返回 0
             失败返回 -1
*/

int slist_insert(NODE** head,DATA pos,DATA data)
{
    NODE *pNew = (NODE*)malloc(sizeof(NODE));
    if(!pNew)
      return  -1;
    pNew -> data = data;
    pNew -> next = NULL;

    NODE *p = *head, *q = NULL;
    if(!p)
    {
        *head = pNew;
        return 0;
    }
    if(memcmp(&(p -> data),&pos,sizeof(DATA)) == 0)
    {
        pNew -> next = *head;
        *head = pNew;
        return 0;
    }
    while(p)
    {
         if(memcmp(&(p -> data),&pos,sizeof(DATA)) == 0)
         {
               pNew -> next = p;
               q -> next = pNew;
               return 0;
         }
         q  = p;
         p  = p -> next;
    }
    q -> next = pNew;
    return 0;
}

/*
@function:   NODE* slist_find(const NODE* head,DATA data);
@berif:      查找链表数据data
@argument:   head: 指向头指针变量
             data: 待查找的数据
@return :    成功返回节点的地址
             失败返回NULL
*/

NODE* slist_find(const NODE* head,DATA data)
{
    const NODE* p = head;
    
    while(p)
    {
         if(memcmp(&(p -> data),&data,sizeof(DATA)) == 0)
         {
             return (NODE*)p;
         }
         p = p -> next;
    }
    return NULL;
}

/*
@function:   int slist_update(const NODE* head,DATA old,DATA newdata);
@berif:      更新链表数据old 为 newdata
@argument:   head: 指向头指针变量
             old:  待更新的节点数据
             newdata: 更新后的节点数据
@return :    成功返回  0
             失败返回  -1
*/

int slist_update(const NODE* head,DATA old,DATA newdata)
{
     NODE* p = NULL;

     if(!(p = slist_find(head,old)))
         return -1;
     p -> data = newdata;
     return 0;
}

/*
@function:   void slist_showAll(const NODE* head);
@berif:      遍历链表数据
@argument:   head: 指向头指针变量
@return :    无
*/

void slist_showAll(const NODE* head)
{
     const NODE*  p  = head;
     int  num = 0;
     printf("%10s%12s%12s%12s%10s\n","车次","起始站","终点站","当前站点","总里程");    
     while(p)
     {
          num++;
          printf("%10d%12s%12s%12s%.1f\n",p->data.line,p->data.start,p->data.stop,\
                                         p->data.current,p->data.km);    
          p = p -> next;
     }
     printf("\n总共有%d条记录\n",num);
}

/*
@function:   int slist_delete(NODE** head,DATA data);
@berif:      删除链表中节点值为data的节点
@argument:   head: 指向头指针变量的地址
             data: 删除节点中的数据
@return :    成功返回 0
             失败返回 -1
*/

int slist_delete(NODE** head,DATA data)
{
    NODE *p = *head, *q = NULL;

    if(!p)
      return -1;
    if(memcmp(&(p -> data),&data,sizeof(DATA)) == 0)
    {
        *head = p -> next;
        free(p);
        return 0;
    }
    while(p)
    {
         if(memcmp(&(p -> data),&data,sizeof(DATA)) == 0)
         {
              q -> next = p -> next;
              free(p);
              return 0;
         }
         q  = p;
         p  = p -> next;
    }
    return -1;
}

/*
@function:   void slist_destroy(NODE** head);
@berif:      回收链表
@argument:   head: 指向头指针变量的地址
@return :    无
*/

void slist_destroy(NODE** head)
{
   NODE* p = *head, *q = NULL;
   
   while(p)
   {
        q = p;
        p = p -> next;
        free(q);
   }
   *head = NULL;
}

function.h

cpp 复制代码
#ifndef __FUNCTION_H
#define __FUNCTION_H

#include "slist.h"

int addrecord(NODE**,int);

int deleterecord(NODE**,int);

void Sort(NODE*,int);

#endif

function.c

cpp 复制代码
#include "function.h"
#include "file.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int addrecord(NODE** head,int sel)
{
    DATA    data = {0};
    
    printf("请输入运行车次:");
    scanf("%d",&(data.line));

    printf("请输入起始站点:");
    scanf("%s",data.start);

    printf("请输入终点站点:");
    scanf("%s",data.stop);
    
    printf("请输入当前站点:");
    scanf("%s",data.current);

    printf("请输入线路总里程:");
    scanf("%f",&(data.km));

    int  ret = 0;

    if(sel == 1)
        ret = slist_addHead(head,data);
    else
        ret = slist_addTail(head,data);
    
     ret = save(*head);
     return ret;
}

static int delete_byline(NODE** head,int line)
{
    NODE* p  = *head;
    while(p)
    {
        if(p -> data.line == line)
              break;
        p  = p -> next;
    }
    if(!p)
       return -1;
       
    return slist_delete(head,p -> data);
} 
static int delete_bystation(NODE** head,const char* station)
{
    NODE* p  = *head;
    while(p)
    {
        if (strcmp(p -> data.stop, station) == 0)
              break;
        p  = p -> next;
    }
    if(!p)
       return -1;
       
    return slist_delete(head,p -> data);
}

int deleterecord(NODE** head,int sel)
{
   char  ch = '\0';
   do
   {
     if(sel == 1)
     {
          int  line = 0;
          printf("请输入要删除的车次:");
          scanf("%d",&line);

          if(delete_byline(head,line) == 0)
          {
               save(*head);
               slist_showAll(*head);
          }
          else
             puts("你删除的车次不存在");
          printf("是否继续删除?[Y/N]");
     }
     else
     {
          char  station[20] ={ 0};
          printf("请输入要删除的终点站:");
          scanf("%s",station);
          if(delete_bystation(head,station) == 0)
          {
               save(*head);
               slist_showAll(*head);
          }
          else
             puts("你删除的车次不存在,");
          printf("是否继续删除?[Y/N]");
     }
     while(getchar()!='\n');
     ch = getchar();     

   }while(ch == 'Y' || ch == 'y');

    return 0;
}

int compare(NODE* p ,NODE* q, int sel)
{
   switch(sel)
   {
       case 1:
            return p -> data.line < q -> data.line;
       case 2:
            return strcmp(p -> data.stop, q -> data.stop) < 0;
       case 3:
            return p -> data.km < q -> data.km;
   }
   return 0;
}

void Sort(NODE* head,int sel)
{
    int n  = 0;
    NODE* p  = head;
     
    while(p)
    {
        n++;
        p  = p -> next;
    }
    NODE** ps = (NODE**)calloc(sizeof(NODE*),n);
    if(!ps)
       return ;
    
    register int  i  = 0;   
    p  = head;
    while(p)
    {
         ps[i++] = p;
         p  = p -> next;
    }

    register int j = 0;

    for(i = 0; i < n -1; i++ )
    {
       int m  = i;   
       for(j  = i + 1; j < n; j++)
       {
             if(compare(ps[m],ps[j],sel))
                 m  = j;
       } 
       if(m != i)
       {
           NODE* t   = ps[i];
           ps[i] = ps[m]; 
           ps[m] = t;
       }
    }

    for(i = 0 ; i < n; i++)
    {
        printf("%6d%-20s%-20s%-20s%-.1f\n",ps[i]->data.line,ps[i]->data.start,ps[i]->data.stop,\
                                           ps[i]->data.current,ps[i]->data.km);
    }

    free(ps);
}

main.c

cpp 复制代码
#include "slist.h"
#include "menu.h"
#include "slist.h"
#include "file.h"
#include <stdio.h>

int main(void)
{
    NODE*  head = NULL;
    
    load(&head);
    welcome();

    while(mainmenu(&head))  ;

    slist_destroy(&head); 
 
    return 0;
} 
相关推荐
朱一头zcy15 分钟前
C语言复习第9章 字符串/字符/内存函数
c语言
此生只爱蛋18 分钟前
【手撕排序2】快速排序
c语言·c++·算法·排序算法
blammmp26 分钟前
Java:数据结构-枚举
java·开发语言·数据结构
何曾参静谧38 分钟前
「C/C++」C/C++ 指针篇 之 指针运算
c语言·开发语言·c++
暗黑起源喵44 分钟前
设计模式-工厂设计模式
java·开发语言·设计模式
昂子的博客1 小时前
基础数据结构——队列(链表实现)
数据结构
WaaTong1 小时前
Java反射
java·开发语言·反射
咕咕吖1 小时前
对称二叉树(力扣101)
算法·leetcode·职场和发展
Troc_wangpeng1 小时前
R language 关于二维平面直角坐标系的制作
开发语言·机器学习
努力的家伙是不讨厌的1 小时前
解析json导出csv或者直接入库
开发语言·python·json