老师链表都讲完了,而我连一次vs都还没有打开。。。
于是周三下午强行学了一波数据结构,然后在这里展示一下思路吧。
线性表,Linear List,是由同类型的数据元素构成的有序序列的线性结构。按照存取的结构不同,分为顺序表和链式表。
实验一要求我们小组写一个基于线性表和链表的图书管理系统,这是一个大程序,一共有20个操作。为了便于说明和组内分工,我先把程序分成了线性表和链表部分两个解决方案,在最后老师验收的时候在合起来并拆分。
我们先来看看线性表:
基本数据结构定义:
#define MAXSIZE 1000 //预先分配的最大容量,书本的最大本数
typedef int Status; //status用来指示函数执行情况,是函数结果状态的表征
#define OK 1
#define ERROR 0
#define OVERFLOW -2
/*基本数据结构定义*/
typedef struct //定义一个叫Book的结构体来表征一本书,内含三个参数
{
char no[20]; //图书ISBN号
char name[50]; //图书名字
float price; //图书价格
}Book;
typedef struct
{
Book *elem; //存储空间的基地址
int length; //图书表中当前图书个数
}SqList; //图书表的顺序存储结构类型叫做SqList
部分代码段:(思路已经呈现在注释中了)
//第一个操作是创建一个空表,输出书本信息与总本书
Status ShowSqList()
{
SqList L; //生成一个顺序表结构
int count; //count用来计算书籍的本书
InitSqList(L, count); //输入大段书籍信息的一个函数
printf("%d\n", count - 1); //打印目前有多少本书
for (int j = 0; j < L.length - 1; j++)
{
printf("%s %s %.2f\n", L.elem[j].no, L.elem[j].name, L.elem[j].price);
}
//输出每本书的信息
return OK;
}
//子函数:
Status InitSqList(SqList& L, int &count) //关于传引用的知识可以去我最近c++的水文里面找
{
L.elem = new Book[MAXSIZE]; //开辟一个足够大的空表
if (!L.elem) exit(OVERFLOW);
L.length = 0; //初始状态长度为0,没有书在表上
Book bk; //新建第“零”本书
bk.price = 1; //假装他有一个价格,便于我们后续启动while语句
count = 0; //书籍也是从0开始算起
while (!(bk.no[0] == '0'&&bk.name[0] == '0'&&bk.price - 0 < 1e-6))
{
//以0 0 0来结束输入
scanf("%s", bk.no);
scanf("%s", bk.name);
scanf("%f", &bk.price);
ListInsert(L, count + 1, bk);
count++;
}
}
Status ListInsert(SqList &L, int i, Book e)
//顺序表的插入,将Book e的数据插入表L的第i个位置上,后面的依次后移一位
{
if (i<1 || i>L.length + 1) return ERROR; //在合法插入范围内插入
if (L.length == MAXSIZE) return ERROR;
//将最后一个到第i个之间所有元素后移,给第i个元素流出空位
for (int j = L.length - 1; j >= i - 1; j--)
L.elem[j + 1] = L.elem[j];
L.elem[i - 1] = e;
L.length++;
return OK;
}
顺序表不怎么用得到指针,所以需要注意的地方并不多。
我们再来康康链表:
基本数据结构定义,大体和顺序表一致:(顺序表的elem就和链表里面的LNode一样代表一个基本单位)
typedef int Status;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
//基本数据结构
typedef struct //图书信息定义
{
char no[20]; //图书ISBN
char name[50]; //图书名字
float price; //图书价格
}Book;
typedef struct LNode
//链表的一个节点,我们叫做LNode,这里的LNode不能省去,因为下面有指向同类的指针
{
Book data; //数据域
struct LNode *next; //指针域,指针指向下一个LNode的结构体类型,我们取名叫next
}LNode, *LinkList; //链表的我们取名叫做LinkList,他代表这个链表的头指针
部分函数段:
//主要函数段
Status ShowLinkList()
{
LinkList L; //L代表链表的头指针
int count; //我们用count来表征有多少个节点
InitLinkList(L); //生成一个空链表
LNode *p; //声明一个指向LNode的p指针
p=new LNode;
FeedData(L,count,p); //输入数据
printf("%d\n", count - 1); //进行打印表的操作,从表头位置开始处理
p = L->next;
while (p->data.price != 0)
{
printf("%s %s %.2f\n", p->data.no, p->data.name, p->data.price);
p = p->next;
}
delete p; //最后需要把这个p指针给delete掉
return OK;
}
//二级函数段
Status InitLinkList(LinkList &L) //生成空链表,产生第一个头节点,其指针域指向NULL
{
L = new LNode;
L->next = NULL; //头结点指针域置空
return OK;
}
Status FeedData(LinkList& L, int &count,LNode *p) //喂入数据
{
LNode *r = L;
count = 0;
while (!(r->data.no[0] == '0'&&r->data.name[0] == '0'&&r->data.price - 0<1e-6))
{
p = new LNode;
scanf("%s %s %f", p->data.no, p->data.name, &p->data.price);
p->next = NULL;
r->next = p;
r = p;
count++;
}
return OK;
}