typedef enum _SListReturn
{
SLIST_RETURN_OK,
SLIST_RETURN_STOP,
SLIST_RETURN_FAIL
}SListReturn;
现在我们从以上代码中选出部分代码来加注释进行讲解。
stud *p,*h,*s; /* *h保存表头结点的指针,*p指向当前结点的前一个结点,*s指向当前结点*/
h->link=NULL; /*把表头结点的链域置空*/
p=h; /*p指向表头结点*/
p->link=s; /*把s的地址赋给p所指向的结点的链域,这样就把p和s所指向的结点连接起来了*/
在代码中除了创建链表的函数外,我们还使用了两个函数,一个是SListReturn print(stud* head)函数,通过该函数我们打印输出链表中的数据。另一个函数是SListReturn destroy(stud* head),通过该函数我们对申请的链表空间进行释放。通过以上函数我想读者应该知道了如何创建一个链表和处理链表中的数据,在这里我仅仅是对数据做了打印操作,如果读者有兴趣可以进行其他的操作。
以上代码实现了单链表的创建,但是链表的常用操作还有查找、插入、删除等没有讲解,删除操作与插入操作类似,就不在这里一一讲解了,在此我们以查找和插入为例进行讲解,但是读者在编写删除操作的时候别忘了把删除的结点释放掉。接下来我们就来看看一段查找和插入的操作。
代码功能为在查找到的结点后面添加一个新的结点。
#include
#include
#include
#include
#define N 3 /*N为人数*/
//#undef _EXAM_ASSERT_TEST_ //禁用
#define _EXAM_ASSERT_TEST_ //启用
#ifdef _EXAM_ASSERT_TEST_ //启用断言测试
void assert_report( const char * file_name, const char * function_name, unsigned int line_no )
{
printf( "\n[EXAM]Error Report file_name: %s, function_name: %s, line %u\n",
file_name, function_name, line_no );
abort();
}
#define ASSERT_REPORT( condition ) \
do{ \
if ( condition ) \
NULL; \
else \
assert_report( __FILE__, __func__, __LINE__ ); \
}while(0)
#else // 禁用断言测试
#define ASSERT_REPORT( condition ) NULL
#endif /* end of ASSERT */
typedef enum _SListReturn
{
SLIST_RETURN_OK,
}SListReturn;
typedef struct node
{
char name[20];
int score;
struct node *link;
}stud;
stud * creat(int n)
{
stud *p,*h,*s;
int i;
if((h=(stud *)malloc(sizeof(stud)))==NULL)
{
printf("分配内存空间失败!");
exit(0);
}
h->name[0]='\0'; /*把表头结点的数据域置空*/
h->score=0;
h->link=NULL; /*把表头结点的链域置空*/
p=h; /*p指向表头结点*/
for(i=0;i
{
if((s= (stud *) malloc(sizeof(stud)))==NULL)
{
printf("分配内存空间失败!");
exit(0);
}
p->link=s; /*把s的地址赋给p所指向的结点的链域,这样就把p和s所指向的结点连接起来了*/
printf("请输入第%d个人的姓名:",i+1);
scanf("%s",s->name); /*姓名*/
printf("请输入第%d个人的成绩:",i+1);
scanf("%d",&s->score); /*分数*/
s->link=NULL;
p=s;
}
return(h);
}
stud * search(stud *h,char *x) /*查找函数*/
{
stud *p;
char *y;
p=h->link;
while(p!=NULL)
{
y=p->name;
if(strcmp(y,x)==0)
return(p);
else p=p->link;
}
if(p==NULL)
printf("没有查找到该数据!");
}
SListReturn insert(stud *p) /*插入函数,在指针p后插入*/
{
char stu_name[20];
int stu_score;
stud *s; /*指针s是保存新结点地址的*/
if((s= (stud *) malloc(sizeof(stud)))==NULL)
{
printf("分配内存空间失败!");
exit(0);
}
printf("请输入你要插入的人的姓名:");
scanf("%s",stu_name);
printf("请输入你要插入的人的成绩:");
scanf("%d",&stu_score);
strcpy(s->name,stu_name); /*把指针stuname所指向的数组元素拷贝给新结点的数据域*/
s->score=stu_score;
s->link=p->link; /*把新结点的链域指向原来p结点的后继结点*/
p->link=s; /*p结点的链域指向新结点*/
return SLIST_RETURN_OK;
}
SListReturn destroy(stud* head)
{
stud* tmp,*next;
tmp=head;
int i=0;
while(tmp!=NULL)
{
next=tmp->link;
tmp->link=NULL;
free(tmp);
tmp=next;
i++;
printf("第%d次释放\n",i);
}
return SLIST_RETURN_OK;
}
SListReturn print(stud* head)
{
stud* tmp=head->link;
while(tmp!=NULL)
{
printf("%s成绩为%d\n",tmp->name,tmp->score);
tmp=tmp->link;
}
return SLIST_RETURN_OK;
}
void main()
{
int number; /*保存人数的变量*/
char fname[10]; /*保存输入的要查找的人的姓名*/
stud *head,*searchpoint; /*head是保存单链表的表头结点地址的指针*/
number=N;
head=creat(number); /*把所新建的单链表表头地址赋给head*/
printf("请输入你要查找的人的姓名:");
scanf("%s",fname);
searchpoint=search(head,fname); /*查找并返回查找到的结点指针*/
insert(searchpoint); /*调用插入函数*/
print(head);
destroy(head);
//ASSERT_REPORT(print(head)==SLIST_RETURN_OK);
//ASSERT_REPORT(destroy(head)==SLIST_RETURN_OK);
}
|