线性表操作——实用算法实验一
实验要求
首先,逐行读取指定文件中的数据,并进行解析后保存在顺序表中。其中,文件中每行数 据格式为“学号,姓名,年龄”,比如“SA10225048,张三,24”。 (注意,给出的例子中分隔符 为一个英文字符。) (提示:采用顺序表结构时,顺序表中每个表元素包含三类信息:学号,姓名,和年龄; 采用单链表结构时,单链表中每个结点的数据域包含三类信息:学号,姓名,和年龄。) 再,根据键盘输入进行相关操作(查找,删除和插入)。比如,若键盘输入为“P3”,则表 示打印出第 3 项的信息(注意:采用顺序表结构时,第 3 项数据对应下标为 2 的表元素; 采用单链表结构时,第 3 项数据对应链表中第 3 个结点的信息;);若键盘输入为“D3”, 则表示删除第 3 个表元素;若键盘输入为“I3,SA10225038,张四,24”,则表示在第 3 项前插 入一个学生的信息(SA10225038,张四,24)。
代码实现
work1.c 数组(顺序表)操作
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define ID_LEN 12
#define NAME_LEN 10
#define MAX_SIZE 20
struct Student{
char id[ID_LEN];
char name[NAME_LEN];
unsigned int age;
};
//trans a string to object Student
Student trans_string_to_std(char *s){
Student std;
//handle id
int i=0,k=0;
while(s[i]!=',') std.id[k++]=s[i++];
std.id[k]=0;
//handle name
k=0;i++;
while(s[i]!=',') std.name[k++]=s[i++];
std.name[k]=0;
//handle age
i++;
std.age=atoi(s+i);
return std;
}
void to_print(Student list[],int len,int index){
if(index>=len) return ;
printf("information of student %d:\n",index+1);
printf(" id: %s\n",list[index].id);
printf(" name: %s\n",list[index].name);
printf(" age: %d\n",list[index].age);
}
void to_delete(Student list[],int &len,int index){
for(int i=index;i<len-1;i++){
list[i]=list[i+1];
}
len--;
printf("delete success!\n");
}
void to_insert(Student list[],int &len,int index,char *s){
Student std=trans_string_to_std(s);
for(int i=len-1;i>=index;i--){
list[i+1]=list[i];
}
list[index]=std;
len++;
printf("insert success!\n");
}
int main(){
//init
char buffer[64]; //input buffer
int len=0; //list len
Student list[MAX_SIZE];
//handle file input
FILE *fp = fopen("Lab1test.DAT","r") ; //you can use args to read the filepath
while(fgets(buffer,64,fp)!=NULL) list[len++]=trans_string_to_std(buffer);
fclose(fp);
for(int i=0;i<len;i++){
printf("%d %s,%s,%d 0x%x\n",i+1,list[i].id,list[i].name,list[i].age,&list[i]);
}
//operating option
//Multiple sets of inputs are used
//Enter Ctrl+Z(EOF) to end
char op;
int op_index;
while(~scanf("%s",buffer)){
bool flag=true;//Check the correctness of the input
op=buffer[0];
op_index=0;
for(int i=1;buffer[i]!=','&&buffer[i]!=0;i++){
if('0'<=buffer[i]<='9') op_index=op_index*10+buffer[i]-'0';
else{
flag=false;
break;
}
}
//if flag is false or op_index is great than the length of list
if(!flag||op_index==0||op_index>len){
printf("your input is incorrect,please try again!\n");
continue;
}
op_index--;
switch (op){
case 'P':
to_print(list,len,op_index);
break;
case 'D':
to_delete(list,len,op_index);
break;
case 'I':
to_insert(list,len,op_index,buffer+3);
break;
default:
printf("your input is incorrect,please try again!\n");
break;
}
}
return 0;
}
work2.c 链表操作
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define ID_LEN 12
#define NAME_LEN 10
#define MAX_SIZE 20
struct Student{
char id[ID_LEN];
char name[NAME_LEN];
unsigned int age;
};
struct ListNode{
Student data;
struct ListNode *next;
};
struct List{
//Member
ListNode *head;
ListNode *tail;
unsigned int count;
//non-parameter constructor
List(){
head=NULL;
tail=NULL;
count=0;
}
void insert_at_tail(ListNode *p){
if(tail==NULL){
head=tail=p;
count=1;
return ;
}
tail->next=p;
tail=p;
count++;
}
void to_delete(int index){
if(index>=count) return ;
//create a prehead to avoid some special situations,such as count=1 or index=0
ListNode *prehead=(ListNode *)malloc(sizeof(ListNode));
prehead->next=head;
//to find the previous points of insertion position
ListNode *p=prehead,*q;
for(int i=0;i<index;i++) p=p->next;
q=p->next;
p->next=p->next->next;
count--;
//handle the special situations of ptx change
head=prehead->next;
if(tail==q) tail=p;
//free the space
free(q);
free(prehead);
printf("delete success!\n");
}
void to_insert(int index,ListNode *node){
if(index>=count) return ;
if(index==0){
node->next=head;
head=node;
return ;
}
ListNode *p=head;
for(int i=0;i<index-1;i++) p=p->next;
node->next=p->next;
p->next=node;
//handle the special situations of tail change
if(tail==p) tail=node;
printf("insert success!\n");
}
void to_print(int index){
if(index>=count) return;
ListNode *p=head;
for(int i=0;i<index;i++,p=p->next);
printf("information of student %d:\n",index+1);
printf(" id: %s\n",(p->data).id);
printf(" name: %s\n",(p->data).name);
printf(" age: %d\n",(p->data).age);
}
};
//trans a string to object Student
Student trans_string_to_std(char *s){
Student std;
//handle id
int i=0,k=0;
while(s[i]!=',') std.id[k++]=s[i++];
std.id[k]=0;
//handle name
k=0;i++;
while(s[i]!=',') std.name[k++]=s[i++];
std.name[k]=0;
//handle age
i++;
std.age=atoi(s+i);
return std;
}
ListNode *trans_student_to_list_node(Student std){
ListNode *node=(ListNode *)malloc(sizeof(ListNode));
node->data=std;
node->next=NULL;
return node;
}
int main(){
//init
char buffer[64]; //input buffer
List list;
//handle file input
FILE *fp = fopen("Lab1test.DAT","r") ; //you can use args to read the filepath
while(fgets(buffer,64,fp)!=NULL){
Student std=trans_string_to_std(buffer);
ListNode *node=trans_student_to_list_node(std);
list.insert_at_tail(node);
}
fclose(fp);
ListNode *p=list.head;
while(p!=NULL){
printf("0x%x 0x%x\n",p,p->next);
p=p->next;
}
//operating option
//Multiple sets of inputs are used
//Enter Ctrl+Z(EOF) to end
char op;
int op_index;
while(~scanf("%s",buffer)){
bool flag=true;//Check the correctness of the input
op=buffer[0];
op_index=0;
for(int i=1;buffer[i]!=','&&buffer[i]!=0;i++){
if('0'<=buffer[i]<='9') op_index=op_index*10+buffer[i]-'0';
else{
flag=false;
break;
}
}
//if flag is false or op_index is great than the length of list
if(!flag||op_index==0||op_index>list.count){
printf("your input is incorrect,please try again!\n");
continue;
}
op_index--;
switch (op){
case 'P':
list.to_print(op_index);
break;
case 'D':
list.to_delete(op_index);
break;
case 'I':
list.to_insert(op_index,trans_student_to_list_node(trans_string_to_std(buffer+3)));
break;
default:
printf("your input is incorrect,please try again!\n");
break;
}
}
return 0;
}