最近在学数据结构,第二章学的线性表,对于从未接触过来说的我 一脸懵逼,赶紧把 C pp 关于链表的基础知识拿过来恶补了一下。
链表的存在是为了克服 用数组储存浪费空间的问题,使用链表之后,可以动态的加入,删除,对于节省 空间有很大的帮助。
下面我们来看一下链表
/*
链表的一些基本知识点:
虽然结构不能含有与本身类型相同的结构,但是可以含有指向同类型结构的 指针,这种定义是定义链表的基础,
链表中的每一项都包含着在何处能找到下一项的信息
所以可以这样来 定义结构
#define TSIZE 45
struct film{
char title[TSIZE];
int rating;
struct film *next;
};
还需要一个 单独的指针储存第一个 结构的指针,该指针被称为 头指针
头指针 指向 链表的第一项
所以 每次我们 创建一个结构之后,我们想加入 新的 节点,我们 可以 令 film->next=current; 我们这样 构成了链式的 结构
假如 要显示这个链表,每显示 一项,就可以根据该项中 已储存的地址来定位下一个带显示的项
然而这种方案能正常运行,还需要一个指针储存一个指针储存链表中第一项的地址,这时候 头指针就派上用场了
*/
#include<stdio.h>
#include<stdlib.h> // 提供malloc() 原型
#include<string.h> //提供 strcpy()原型
#define TSIZE 45
struct film{
char title[TSIZE];
int rating;
struct film *next; //指向链表中下一个结构
};
char * s_gets(char * st,int n);
int main()
{
struct film *head=NULL; //定义一个头结点
struct film *prev,*current;
char input[TSIZE];
// 收集并储存信息
puts("Enter first movie title:");
while(s_gets(input,TSIZE)!=NULL && input[0]!='\0')
{
current=(struct film *)malloc(sizeof(struct film)); //分配 空间
if(head==NULL) // 第一个结构
head=current;
else
prev->next=current;
current->next=NULL;
strcpy(current->title,input);
puts("Enter your rating <0-10>:");
scanf("%d",¤t->rating);
while(getchar()!='\n')
continue;
puts("Enter next movie title (empty line to stop)");
prev=current;
}
// 显示电影列表
if(head ==NULL)
printf("No data entered.");
else
printf("Here id the movie list:\n");
// 为何重新创建一个新指针呢? 因为如果使用head 会改变head 中的值,程序就找不到链表的开始处
current=head;
while(current!=NULL)
{
// 使用指针表示法 来访问结构的成员变量
printf("Movie: %s Rating: %d \n",current->title,current->rating);
// 重新设置current指针指向链表中的下一个结构
current=current->next;
}
//完成任务,释放已分配的内存
current=head;
while(current !=NULL)
{
current =head;
head =current->next;
free(current);
}
printf("Bye!\n");
return 0;
}
char * s_gets(char *st ,int n)
{
char *ret_val;
char *find;
ret_val=fgets(st,n,stdin);
if(ret_val)
{
find = strchr(st,'\n'); //查找换行符
if(find) // 如果查找地址不是NULL
*find='\0'; //在此放置一个空字符
else
while(getchar()!='\n')
continue; //处理剩余输入行
}
return ret_val;
}