链表—简易数据操作

#include<stdio.h>

#include<stdlib.h>

#include <windows.h>

#include<conio.h>

//#definefun_name(x) printf("%s ", #x)  //定义把变量名转换成字符串 ???如何获取结构体中变量名等信息

 

//********定义数据结构********

typedef struct student {

   int     rec_id=NULL;//设置默认值??对否

   char    name[20]="";

   float   fs=0;

   struct  student * p_next=NULL;

} STD;

 

//*******声明子函数******

STD * record_create();                 //1、生成链表

void record_add(STD * p_head);           //2、添加数据

void record_insert(STD * p_head);        //3、插入数据

void record_sort(STD * p_head);          //4、链表排序

void record_list(STD * p_head);          //5、显示数据

void record_input(STD * p_head);         //6、导入数据

void record_output(STD *p_head);              //7、导出数据

bool rls(STD * p_head )  ;                //释放链表的函数

void paint_head();                     //8、绘制介面

bool isempty(STD * p);                   //判定链表是否为空

 

// 0、**********主函数开始**********

int main(void){

   STD* p_head=NULL;                //定义STD型指针变量,标识链表头地址,并初始化

 

   while(1){                             //****主循环,保持所有操作都在主界面控制下****

      system("cls");                //清屏并

      paint_head();              //调用绘制主界面函数

 

      inti=0;

      charselect=NULL;             //初始化选项标识变量

      scanf("%c",&select);             //接受选择项      //select=getchar();

      if(select=='\n')             //当直接回车时,返回、重载主界面

        continue;                  //????必须放到前 while(getchar()!='\n') _下一句增加闪烁光标

 

      while(getchar()!='\n')           //判断输入字符的个数

        i++;

      if(i>0)                      //当输入多个字符时,无效、返回

        continue;

 

      switch(select){     //**********以下是主菜单选择部分************

           //新建链表

        case'1':

        case'n':

        case'N'://分析是否已存存链表

           if(p_head!= NULL){

              printf("\n\n链表已经存在按任意键,继续!");

              system("pause>nul");

              break;

           } else

              p_head=record_create();

           break;

           //添加节点

        case'2':

        case'a':

        case'A':

           record_add(p_head);

           break;

           //插入节点

        case'3':

        case'i':

        case'I':

           record_insert(p_head);

           break;

           //排序数据

        case'4':

        case'Y':

        case'y':

           record_sort(p_head);

           break;

           //显示数据

        case'5':

        case'v':

        case'V':

           record_list(p_head);

           break;

           //导入数据

        case'6':

        case'r':

        case'R':

           record_input(p_head);

           break;

           //导出数据

        case'7':

        case's':

        case'S':

           record_output(p_head);

           break;

           //退出系统

        case'8':

        case'q':

        case'Q':{

              printf("\n\n按任意建,退出程序!");

              rls(p_head);

              exit(0);

              break;

           }

        default:

           continue;

      }

      //********以上是:主菜单选择部分********

   }

 

   return0;

}

//*********主函数main()结束********

 

//0、判定链表是否为空

bool isempty(STD * p_head){

   if(p_head==NULL){

      printf("\n\n ");

      system("echo 请先创建链表,按任意键返回主菜单!");

      system(" pause>nul");

      system("cls");

      returntrue;

   } else {

      system("cls");

      returnfalse;

   }

}

 

//1、********建立链表********

STD * record_create(){

   system("cls");                                 //清屏

   printf("现在创建新链表!\n\n");

 

   STD*p_head=NULL;

   STD*p_old=NULL;

   STD*p_new=NULL;

   inti=0;

   intlen;

 

   printf("请输入要存储记录的条数 N:");

   while  (scanf("%d",&len)<1){

      system("\n echo 非法输入,请按重新输入数字!");

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

   }

   p_new=(STD *)malloc(sizeof(STD));

   if(p_new==NULL){                  //检测内存空间申请是否成功

      printf("\n链表生成失败!");

      returnNULL;

   }

   p_new->p_next=NULL;       //这里是p_new所指向在STD型变量的成员p_next的值为NULL,而不是p_new所存储的地址信息变了.变的是其指向的STD型 结构体中用以存储下一地址的成员变量值

   p_old=p_new;

   p_head=p_new;

 

   for(i=0; i<len; i++){

      p_new=(STD *)malloc(sizeof(STD));

      if(p_new==NULL){

        printf("\n链表生成中断!");

        break;

      }

      p_new->p_next=NULL;

      p_old->p_next=p_new;

      p_old=p_new;

 

      printf("\n输入第%d个结点的信息:\n",(i+1));

      printf(学号:");

      scanf("%d",&p_new->rec_id);

      printf(姓名:");

      scanf("%s",&p_new->name);

      printf(成绩:");

      scanf("%f",&p_new->fs);

 

      if(i<len-1){                //根据需要选择是否,中断输入!

        printf("\n按ESC键,返回主介面,任意键继续!\n");

        if(getch()==27) break;

      }

   }

 

   //system("\n\necho 新建链表成功,按任意键退出!");

   printf("\n新建链表成功,按任意键退出!\n");

   system("pause>nul");

 

   returnp_head;

}

 

//2、*******添加数据********

void record_add(STD * p_head){

   if(isempty(p_head))     //无链表结构时,即出!

      return;

 

   STD*p_cur;

   STD*p_new;

   p_cur=p_head;                           //以p_add表示当前结点,首先把头结点做为当前结点

 

   while(NULL!=p_cur->p_next)              //判断下当前结点的地址域是否为空,即是否链表尾,不为空看下一结点

      p_cur=p_cur->p_next;                //把下结点的地址传给p_add,直到 p_add指向尾结点,此时 p_add地址域为NULL!!

 

   inti,len=0;

   printf("\n请输入要添加记录的条数 N:");

   if(scanf("%d",&len)<1){                        //保证输入数字

      system("\n echo 非法输入,请按任意键退出!");

      system("pause>nul");

      return;

   }

 

   for(i=0; i<len; i++){

      p_new=(STD *)malloc(sizeof(STD));              //申请内容空间,并把地址放到原链表尾地址变量中

      p_new->p_next=NULL;

      p_cur->p_next=p_new;

      p_cur=p_new;

      printf("\n输入添加的第%d个结点的信息:\n",(i+1));

      printf(学号:");

      scanf("%d",&p_new->rec_id);               //等同于 scanf("%d",&((*p_new).rec_id));

      printf(姓名:");

      scanf("%s",&p_new->name);

      printf(成绩:");

      scanf("%f",&p_new->fs);

      printf("\n");

      if(i<len-1){                //根据需要选择是否,中断输入!

        printf("\n按ESC键,返回主介面,任意键继续!\n");

        if(getch()==27) break;

      }

   }

   printf("\n数据添加成功,按任意键退出!\n");

   system("pause>nul");

   return;

}

 

//3、*******插入数据********

void record_insert(STD * p_head){

   if(isempty(p_head))          //无链表结构时,即出!

      return;

   STD* p_cur;                    //定义结构体变量

   STD* p_previous;

   STD* p_new;

 

   intvalue=0;               //统计总结点数

   intposition=0;               //设置插入点位置

 

   p_cur=p_head->p_next;         //设置头结点的地址域指向的结点(即第一个存储有效值的结点,也即首结点)为当前结点

   while(NULL!=p_cur){           //统计总结点数,不包括点结点。比实际结点少一个!!!!!!!!!

      value++;

      p_cur=p_cur->p_next;

   }

   printf("当前链表有效结点总数为: %d\n",value);

   printf("请输入数据插入第几个结点前面:");

   while((scanf("%d",&position)<1)||(position>value)){    //保证输入数字,并不超限

      if  (position>value)

        system("\n echo 输入超限,请重新输入数字或选择添加!");

      else

        system("\n echo 输入错误,请重新输入数字!");

      while(getchar()!='\n');                       //清除缓冲区残留的字符,分号是空语句,while不包括continue

      continue;

   }

 

   //下面和插入节点    “当插入点为1时,插入到头结点与首结点之间”,在头结点前不插入任何结点

   value=0;                    //计数置零

   p_previous=p_head;               //把头结点 设置为上一结点

   p_cur=p_head->p_next;                   //把首结点 设置为当前结点

 

   while(NULL!=p_cur){               //遍历结点,直到插入点。

      value++;                        //当前结点,即检测指针指向结点不为空时,计数加1

      if(value==position){

        p_new=(STD *)malloc(sizeof(STD));

        if(p_new!=NULL){

           p_new->p_next=p_previous->p_next;

           p_previous->p_next=p_new;

           printf("\n输入插入结点的信息:\n");

           printf(学号:");

           scanf("%d",&p_new->rec_id);               //等同于 scanf("%d",&((*p_new).rec_id));

           printf(姓名:");

           scanf("%s",&p_new->name);

           printf(成绩:");

           scanf("%f",&p_new->fs);

           printf("\n");

           break;

        }

      }

      p_previous=p_cur;

      p_cur=p_cur->p_next;

   }

 

   system("\n echo 数据插入成功,按任意键退出!");

   system("pause>nul");

}

 

//4、*******数据排序****采用冒泡排序法****//数据对应错误!!!!!!

 

void record_sort(STD *p_head){

   if(isempty(p_head))     //无链表结构时,即出!

      return;

 

   STD*p_curr=NULL;

   STD*p_next=NULL;

   float  val;

   inti,j;

   p_curr=p_head;

   p_next=p_head;              //指针变量初始化

 

 

   for( p_curr=p_head; p_curr!=NULL && p_curr->p_next!=NULL; p_curr=p_curr->p_next)      //从表头循环到表尾

 

      for(p_next=p_curr->p_next; p_next!=NULL&&p_next->p_next!=NULL;p_next=p_next->p_next){//对于外循环的每一个节点,取其后的最小值到当前节点

 

        if(p_curr->p_next->fs > p_next->p_next->fs){//对内循环的每两个相邻节点,取其小的放前,大的后放后

           val= p_curr->p_next->fs;   

            p_curr->p_next->fs=p_next->p_next->fs;

           p_next->p_next->fs=val;

        }

      }

   return;

}

//5、*******显示数据********

 

void record_list(STD * p_head){

   if(isempty(p_head))     //无链表结构时,即出!

      return;

//*************************************************以下定义表头**************

   inti;

   STD* p_list;

   p_list=p_head->p_next;

   printf("\n当前输入数据有:\n\n");

 

   for(i=0; i<20; i++)

      printf("* ");

   printf("\n%s\n"," rec_id  | name                 |fs");

   printf("%s\n"  ,"--------+----------------------+----- ");

//*****************************************以上定义表头,以下输入数据********

 

   while(p_list){//  while(NULL!=p_list->p_next)//不能输出最后一相结点的数据,因 p_list->p_next为空时,循环就结束了

      printf(" %-7d | %-20s |%-10f\n",(*p_list).rec_id,p_list->name,p_list->fs);//(*p_list).rec_id等同于p_list->rec_id;

      p_list=p_list->p_next;

   }

   printf("\n\n");

   system("\n echo 显示结束,请按任意键退出!");

   system("pause>nul");

   return;

}

 

//6、*******导入数据********

void record_input(STD * p_head){

   system("cls");

 

   FILE*fp;

   intc;

   if((fp = fopen("d:\\jhm.txt","r"))!=NULL){

      while(1){

        c= fgetc(fp);

        if( feof(fp)){

           break;

        }

        printf("%c", c);

      }

   } else

      printf("文件打开失败\n");

   printf("\n\n");

   system("\n echo 显示结束,请按任意键退出!");

   system("pause>nul");

   fclose(fp);

   return;

}

 

//7、*******导出数据********

void record_output(STD * p_head){

   if(isempty(p_head))     //无链表结构时,即出!

      return;

 

   STD* p_write,* p_term;

   FILE* fp;

 

   if((fp=fopen("d:\\jhm.txt","wt+"))==NULL){

      printf("\n打开文件失败!返回! ");

      getchar();

      return;

   }

   p_write=p_head->p_next;

   while(NULL!=p_write){

      fprintf(fp,"%-6d",p_write->rec_id );        //-左对齐,+右对齐

      // fprintf(fp,"%s",",");

      fprintf(fp,"%-20s",p_write->name);

      // fputs(",",fp);

      fprintf(fp,"%-10f",p_write->fs );

      fputs("\n",fp);

      p_write=p_write->p_next;

   }

   system("\n echo 已经成功执行,请按任意键退出!");

   system("pause>nul");

   fclose(fp);

   return;

}

 

//释放链表的函数---未验证

bool rls(STD * p_head){

   STD* p_cur,*p_del;

   p_cur=p_head;

   p_del=p_head;

 

   while(NULL!=p_cur){

      p_cur=p_cur->p_next;

      free(p_del);

      //p_del=NULL;

      p_del=p_cur;

   }

}

 

//*******画主菜单*********//

void paint_head(){

   // 设置字体颜色(高亮)

   SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),14);

   inti;

   constint num_top_btn=30,num_mid=57,num_lr=5;  //定义常量,存储间隔的空格数,便于修改

 

   // ******打出第一行星号 ******

   for(i=0; i<num_top_btn; i++)

      printf("* ");

 

   // * * * * 打出第二行  * * * *

   printf("\n*");                         //行首*

   for(i=0; i<num_mid; i++)                //行空格

      printf(" ");

   printf("*");                         //行尾*

 

   // * * * * 打出第三行 * * * *

   printf("\n*");                               //行首*

   for(i=0; i<num_lr; i++)

      printf(" ");

   printf("1、新建链表<\"n\"或\"N\">");

   for(i=0; i<num_lr; i++)

      printf(" ");

   printf("2、添加数据<\"a\"或\"A\">");

   for(i=0; i<num_lr; i++)

      printf(" ");

   printf("*");                                  // 行尾*

 

   // * * * *打出第四行 * * * *

   printf("\n*");                               //行首*

   for(i=0; i<num_mid; i++)                        //行空格

      printf(" ");

   printf("*");                               //行尾*

 

   // * * * * 打出第五行 * * * *

   printf("\n*");                               //行首*

   for(i=0; i<num_lr; i++)

      printf(" ");

   printf("3、插入数据<\"I\"或\"i\">");

   for(i=0; i<num_lr; i++)

      printf(" ");

   printf("4、数据排序<\"P\"或\"p\">");

   for(i=0; i<num_lr; i++)

      printf(" ");

   printf("*");                                  // 行尾*

 

   // * * * * 打出第六行 * * *  *

   printf("\n*");                               //行首*

   for(i=0; i<num_mid; i++)                        //行空格

      printf(" ");

   printf("*");                                   //行尾*

 

   // * * * *打出第七行 * * * *

   printf("\n*");                               //行首*

   for(i=0; i<num_lr; i++)

      printf(" ");

   printf("5、显示数据<\"S\"或\"s\">");

   for(i=0; i<num_lr; i++)

      printf(" ");

   printf("6、打开文件<\"Q\"或\"q\">");

   for(i=0; i<num_lr; i++)

      printf(" ");

   printf("*");                                   // 行尾*

 

   // * * * * 打出第八行  * * * *

   printf("\n*");                                //行首*

   for(i=0; i<num_mid; i++)                       //行空格

      printf(" ");

   printf("*");                               //行尾*

 

   // * * * *打出第九行  * * * *

   printf("\n*");                               //行首*

   for(i=0; i<num_lr; i++)

      printf(" ");

   printf("7、保存文件<\"S\"或\"s\">");

   for(i=0; i<num_lr; i++)

      printf(" ");

   printf("8、退出系统<\"Q\"或\"q\">");

   for(i=0; i<num_lr; i++)

      printf(" ");

   printf("*");                                     // 行尾*

 

   // *****打出最后一行星号 ******

   printf("\n*");                                 // 行首*

   for(i=0; i<num_mid; i++)                     //中间空格

      printf(" ");

   printf("*\n");                               //行尾*

   for(i=0; i<num_top_btn; i++)               //最后一行的*

      printf("* ");

 

   // ****设置字体颜色(还原)****

   printf("\n\n\n       请按相应数字或字符,选择所要进行的操作:");

   SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),15);

}

 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值