测试题:
0. 同样的数据,存储在单链表中会比存储在数组中至少多占用一倍的空间,对吗?^
答:不对,占用的空间基本是一样的(错误)
答案:对的,因为单链表除了有“头”有“尾”,每个数据节点还得存放一个指向下一个节点的指针。
1. 相比起头插法,尾插法有什么优势?
答:不清楚(错误)
答案:尾插法保证了单链表内部的数据的存储顺序与插入的顺序一致。
2. 有人说,尾插法的劣势可能就是效率偏低,因为每次插入都需要从头遍历整个单链表,对此,你有什么改进的方案吗?
答:这个确实没有(错误)
答案:可以添加一个静态指针,让该指针永远指向单链表的尾部位置。
3. 对于单链表搜索,请问最好情况和最坏情况应该怎样的?
答:最好的在第一个搜索到,最坏的在最后一个搜索到
答案:最好的情况就是待查找的元素就在表头,那么仅需要比较一次即可;最坏的情况是待查找的元素在表尾(或不存在),那么需要迭代比较整个单链表的所有节点。
4. 请问下面 A 代码和 B 代码的执行结果是一样的吗?
A:
...
void releaseLibrary(struct Book **library)
{
struct Book *temp;
while (*library != NULL)
{
temp = *library;
*library = (*library)->next;
free(temp);
}
}
...
int main(void)
{
struct Book *library = NULL;
...
releaseLibrary(&library);
return 0;
}
B:
...
void releaseLibrary(struct Book *library)
{
struct Book *temp;
while (library != NULL)
{
temp = library;
library = library->next;
free(temp);
}
}
...
int main(void)
{
struct Book *library = NULL;
...
releaseLibrary(library);
return 0;
}
答:一样的
答案:完全一样。
解析:释放空间跟打印数据(void printLibrary(struct Book *library))一样,只需要能够拿到每个成员的地址,就可以释放它。
动动手:
0. 将这两节课的书籍管理程序的代码给整理一下吧,课堂听课似乎理解了,事后自己做题又觉得有些怀疑,对不对?不妨趁热打铁,将代码整理一下,有助于进一步加深印象!#
要求实现以下两个关键功能:
- 书籍录入(使用尾插法)
- 书籍搜索(支持书名或作者搜索)
程序实现如下:
#include <stdio.h>
#include <stdlib.h>
struct Book
{
char name[32];
char author[16];
struct Book *next;
};
void getInput(struct Book *book)
{
printf("请输入书名:");
scanf("%s",book->name);
printf("请输入作者:");
scanf("%s",book->author);
}
void printbook(struct Book *book)
{
printf("书名:",book->name);
printf("作者:",book->author);
}
void addBook(struct Book **library)
{
struct Book *book;
static struct Book *tail;
book = (struct Book *)malloc(sizeof(struct Book));
if(book == NULL)
{
printf("内存分配失败\n");
exit(1);
}
getInput(book);
if(*library == NULL) //第一次调用的时候
{
*library = book;
book->next = NULL;
}
else //后续调用此函数
{
// *library = book; //增加此行更好理解
tail->next = book;
book->next = NULL;
}
tail = book;
}
void releaseLibrary(struct Book **library)
{
struct Book *book;
while(*library != NULL)
{
book = *library;
*library = (*library)->next;
free(book);
}
}
struct Book *searchBook(struct Book *library,char * target)
{
struct Book *book;
book = library;
while(book != NULL)
{
if(!strcmp(book->author,target) || !strcmp(book->name,target))
printf("没有符合条件的书籍\n");
else{
printf("已找到符合条件的书籍\n");
break;
}
book = book->next;
}
return book;
}
int main()
{
struct Book *book = NULL;
struct Book *library = NULL;
char input[32];
char ch;
printf("=====录入功能测试=====\n");
while(1)
{
printf("是否添加书籍(Y/N):");
do{
ch = getchar();
}
while((ch != 'Y') && (ch != 'N'));
if(ch == 'Y')
{
addBook(&book);
}
else{
break;
}
}
printf("=====搜素功能测试=====\n");
printf("请输入符合条件的书籍:");
scanf("%s",input);
book = searchBook(library,input);
if(book != NULL)
{
do{
printf("已经找到符合条件的书籍\n");
printbook(book);
}
while((book = searchBook(book->next, input)) != NULL); //这里没明白为什么还要while
}
else{
printf("没有符合条件的书籍\n");
}
releaseLibrary(&library);
}
答案:
#include <stdio.h>
#include <stdlib.h>
struct Book
{
char title[128];
char author[40];
struct Book *next;
};
void getInput(struct Book *book)
{
printf("请输入书名:");
scanf("%s", book->title);
printf("请输入作者:");
scanf("%s", book->author);
}
void addBook(struct Book **library)
{
struct Book *book;
static struct Book *tail;
book = (struct Book *)malloc(sizeof(struct Book));
if (book == NULL)
{
printf("内存分配失败!\n");
exit(1);
}
getInput(book);
if (*library != NULL)
{
tail->next = book;
book->next = NULL;
}
else
{
*library = book;
book->next = NULL;
}
tail = book;
}
void printBook(struct Book *book)
{
printf("书名:%s\n", book->title);
printf("作者:%s\n", book->author);
}
struct Book *searchBook(struct Book *library, char *target)
{
struct Book *book;
book = library;
while (book != NULL)
{
if (!strcmp(book->title, target) || !strcmp(book->author, target))
{
break;
}
book = book->next;
}
return book;
}
void releaseLibrary(struct Book **library)
{
struct Book *temp;
while (*library != NULL)
{
temp = *library;
*library = (*library)->next;
free(temp);
}
}
int main()
{
struct Book *book = NULL;
struct Book *library = NULL;
char input[128];
char ch;
printf("\n====== 录入功能测试 ======\n");
while (1)
{
printf("是否添加书籍(Y/N):");
do
{
ch = getchar();
} while (ch != 'Y' && ch != 'N');
if (ch == 'Y')
{
addBook(&library);
}
else
{
break;
}
}
printf("\n====== 搜素功能测试 ======\n");
printf("请输入书名或作者:");
scanf("%s", input);
book = searchBook(library, input);
if (book == NULL)
{
printf("很抱歉,没能找到!\n");
}
else
{
do
{
printf("已找到符合条件的书籍...\n");
printBook(book);
} while ((book = searchBook(book->next, input)) != NULL);
}
releaseLibrary(&library);
return 0;
}
1. 代码都是写出来的,请大家依葫芦画瓢,编写一个事件备忘录(代码完全可以参照我们的图书管理程序)。
要求实现以下两个关键功能:
- 事件录入(使用尾插法)
- 事件搜索(根据日期)
- 事件打印(按顺序打印)
程序实现如下:
答:
#include <stdio.h>
#include <stdlib.h>
struct DATE
{
int year;
int month;
int day;
};
struct Book
{
struct DATE date;
char envent[32];
struct Book *next;
};
void getInput(struct Book *book)
{
printf("日期(yy-mm-dd):");
scanf("%d-%d-%d",&(book->date.year),&(book->date.month),&(book->date.day));
printf("请输入事件:");
scanf("%s",book->envent);
}
void printbook(struct Book *book)
{
printf("日期:%d-%d-%d",book->date.year,book->date.month,book->date.day);
printf("作者:%s",book->envent);
}
void addBook(struct Book **library)
{
struct Book *book;
static struct Book *tail;
book = (struct Book *)malloc(sizeof(struct Book));
if(book == NULL)
{
printf("内存分配失败\n");
exit(1);
}
getInput(book);
if(*library == NULL) //第一次调用的时候
{
*library = book;
book->next = NULL;
}
else //后续调用此函数
{
// *library = book; //增加此行更好理解
tail->next = book;
book->next = NULL;
}
tail = book;
}
void releaseLibrary(struct Book **library)
{
struct Book *book;
while(*library != NULL)
{
book = *library;
*library = (*library)->next;
free(book);
}
}
struct Book *searchBook(struct Book *library,struct DATE *hu)
{
struct Book *book;
book = library;
struct DATE *str;
str = hu;
while(book != NULL)
{
if(library->date.year == str->year && library->date.month == str->month && library->date.day == str->day)
{
printf("有符合条件的书籍\n");
break;
}
else{
}
book = book->next;
}
return book;
}
int main()
{
struct Book *book = NULL;
struct Book *library = NULL;
char input[32];
char ch;
printf("=====录入功能测试=====\n");
while(1)
{
printf("是否添加书籍(Y/N):");
do{
ch = getchar();
}
while((ch != 'Y') && (ch != 'N'));
if(ch == 'Y')
{
addBook(&library);
}
else{
break;
}
}
struct DATE test;
printf("=====搜素功能测试=====\n");
printf("请输入日期:");
scanf("%d-%d-%d",&(test.year),&(test.month),&(test.day));
book = searchBook(library,&test);
if(book != NULL)
{
do{
printf("已经找到符合条件的书籍\n");
printbook(book);
}
while((book = searchBook(book->next, &test)) != NULL); //这里没明白为什么还要while
}
else{
printf("没有符合条件的事件\n");
}
releaseLibrary(&library);
}
答案:
#include <stdio.h>
#include <stdlib.h>
struct Date
{
int year;
int month;
int day;
};
struct Event
{
char content[128];
struct Date date;
struct Event *next;
};
void getInput(struct Event *event)
{
printf("日期(yy-mm-dd):");
scanf("%d-%d-%d", &event->date.year, &event->date.month, &event->date.day);
printf("事件:");
scanf("%s", event->content);
}
void addEvent(struct Event **memo)
{
struct Event *event;
static struct Event *tail;
event = (struct Event *)malloc(sizeof(struct Event));
if (event == NULL)
{
printf("内存分配失败!\n");
exit(1);
}
getInput(event);
if (*memo != NULL)
{
tail->next = event;
event->next = NULL;
}
else
{
*memo = event;
event->next = NULL;
}
tail = event;
}
void printMemo(struct Event *memo)
{
struct Event *event;
event = memo;
while (event != NULL)
{
printf("日期:%d-%d-%d\n", event->date.year, event->date.month, event->date.day);
printf("事件:%s\n", event->content);
event = event->next;
}
}
void printEvent(struct Event *event)
{
printf("日期:%d-%d-%d\n", event->date.year, event->date.month, event->date.day);
printf("事件:%s\n", event->content);
}
int cmpDate(struct Date d1, struct Date d2)
{
if (d1.year == d2.year && d1.month == d2.month && d1.day == d2.day)
{
return 1;
}
else
{
return 0;
}
}
struct Event *searchEvent(struct Event *memo, struct Date date)
{
struct Event *event;
event = memo;
while (event != NULL)
{
if (cmpDate(event->date, date))
{
break;
}
event = event->next;
}
return event;
}
void releaseMemo(struct Event *memo)
{
struct Event *temp;
while (memo != NULL)
{
temp = memo;
memo = memo->next;
free(temp);
}
}
int main()
{
struct Event *memo = NULL;
struct Event *event = NULL;
struct Date date;
char ch;
printf("\n====== 录入功能测试 ======\n");
while (1)
{
printf("是否添加记录(Y/N):");
do
{
ch = getchar();
} while (ch != 'Y' && ch != 'N');
if (ch == 'Y')
{
addEvent(&memo);
}
else
{
break;
}
}
printf("\n====== 查找功能测试 ======\n");
printf("请输入日期:");
scanf("%d-%d-%d", &date.year, &date.month, &date.day);
event = searchEvent(memo, date);
if (event == NULL)
{
printf("很抱歉,没能找到!\n");
}
else
{
do
{
printf("已经找到该日期的事件...\n");
printEvent(event);
} while((event = searchEvent(event->next, date)) != NULL);
}
printf("\n====== 打印功能测试 ======\n");
printMemo(memo);
releaseMemo(memo);
return 0;
}