S1E46:单链表2(尾插法) 课后作业

测试题:
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. 将这两节课的书籍管理程序的代码给整理一下吧,课堂听课似乎理解了,事后自己做题又觉得有些怀疑,对不对?不妨趁热打铁,将代码整理一下,有助于进一步加深印象!#
要求实现以下两个关键功能:

  • 书籍录入(使用尾插法)
  • 书籍搜索(支持书名或作者搜索)

程序实现如下:

答:参照答案写的  tail 定义为静态变量,tail = book,每次添加完后使得tail指向链表尾部

#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;
}

  • 21
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值