1、slist_head_loop.h
/*
* slist_head_loop.h
* 描述:
* 有头循环单链表
*/
#pragma once
#include <stdio.h>
#include <stdlib.h>
typedef struct _student_info
{
char name[10];
int num;
int age;
}student_info;
struct node_info
{
student_info stu;
struct node_info*next;
};
void slist_init_head(struct node_info *head);
void slist_add(struct node_info *head,student_info stu);
void slist_add_tail(struct node_info *head,student_info stu);
void slist_del(struct node_info *head,student_info stu);
void slist_for_each(struct node_info *head);
void slist_destroy(struct node_info *head);
2、slist_head_loop.c
/*
* slist_head_loop.c
*
*/
#include "slist_head_loop.h"
/*
* 初始化头节点:
* 节点指针指向自己(只有一个节点)
*/
void slist_init_head(struct node_info *head)
{
head->next = head;
}
/*
* 链表头插:
* 在头节点的后面插入
*/
void slist_add(struct node_info *head,student_info stu)
{
/*
* 为新节点申请空间
*/
struct node_info *new_node = (struct node_info *)malloc(sizeof(struct node_info));
new_node->stu = stu;
/*
* 插入操作
*/
new_node->next = head->next;
head->next = new_node;
}
/*
* 链表尾插:
* 遍历链表,然后在尾部插入
*/
void slist_add_tail(struct node_info *head,student_info stu)
{
struct node_info *new_node = (struct node_info *)malloc(sizeof(struct node_info));
new_node->stu = stu;
struct node_info *cur = NULL;
//找到最后一个节点的地址
for(cur = head->next;cur->next != head;cur = cur->next)
{
//什么都不做
}
//此时cur指向最后一个节点
new_node->next = head;
cur->next = new_node;
}
/*
* 删除节点:
* 遍历链表,找到与要删除的元素相同的节点
*/
void slist_del(struct node_info *head,student_info stu)
{
struct node_info *tmp = NULL;
struct node_info *cur = NULL;
for(tmp = head,cur = head->next;cur != head;tmp = tmp->next,cur = cur->next)
{
if(strcmp(cur->stu.name , stu.name) == 0 && cur->stu.num == stu.num && cur->stu.age == stu.age)
{
//删除cur节点
tmp->next = cur->next;
cur->next = cur;
free(cur);
//退出循环
break;
}
}
// struct node_info *cur = head->next;
// struct node_info *tmp = head;
// while (cur != head) {
// if (cur->data == data) {
// tmp->next = cur->next;
// free(cur);
// cur = tmp->next;
// } else {
// tmp = cur;
// cur = cur->next;
// }
// }
}
/*
* 打印链表节点:
* 遍历每个节点
*/
void slist_for_each(struct node_info *head)
{
struct node_info *cur = NULL;
for(cur = head->next;cur != head;cur = cur->next)
{
printf("\t%s\t%d\t%d\n",cur->stu.name,cur->stu.num,cur->stu.age);
}
}
/*
*销毁链表:
* 删除链表中的每个元素
*/
void slist_destroy(struct node_info *head)
{
struct node_info *tmp = head->next;
for (tmp = head->next; tmp != head; tmp = head->next) {
head->next = tmp->next;
free(tmp);
}
/* while (head->next != head) {
* free(head->next);
* head->next = head->next->next;
* }*/
}
3、test.c
/*
* test.c
* data:
* 2014-07-28
*/
#include "slist_head_loop.h"
int main()
{
struct node_info head;
int i;
student_info stu[] = {
{"lind",21,21},
[1]={
.name = "dave",
.num = 10,
.age = 20
},
{"take",14,23}
};
slist_init_head(&head);
for(i = 0;i < 3;i ++)
{
slist_add(&head,stu[i]);
}
printf("\t本班的学生信息如下:\n");
printf("\t姓名\t学号\t年龄\n");
slist_for_each(&head);
student_info stu1[] = {
{"Tiger",1,21},
[1]={
.name = "jime",
.num = 13,
.age = 20
},
{"Tame",16,23}
};
for(i = 0;i < 3;i ++)
{
slist_add_tail(&head,stu1[i]);
}
printf("\t增加新人后本班的学生信息如下:\n");
printf("\t姓名\t学号\t年龄\n");
slist_for_each(&head);
slist_del(&head,stu[1]);
printf("\tdava离开后本班的学生信息如下:\n");
printf("\t姓名\t学号\t年龄\n");
slist_for_each(&head);
slist_destroy(&head);
}
4、Makefile
all:test
test:test.o slist_head_loop.o
gcc -o $@ $^
test.o:test.c
gcc -c test.c
slist_head_loop.o:slist_head_loop.c
gcc -c slist_head_loop.c
clean:
rm *.o test
5.运行结果
workspace/project/slist_head_loop# valgrind ./test
==8720== Memcheck, a memory error detector
==8720== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==8720== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==8720== Command: ./test
==8720==
本班的学生信息如下:
姓名 学号 年龄
take 14 23
dave 10 20
lind 21 21
增加新人后本班的学生信息如下:
姓名 学号 年龄
take 14 23
dave 10 20
lind 21 21
Tiger 1 21
jime 13 20
Tame 16 23
dava离开后本班的学生信息如下:
姓名 学号 年龄
take 14 23
lind 21 21
Tiger 1 21
jime 13 20
Tame 16 23
==8720==
==8720== HEAP SUMMARY:
==8720== in use at exit: 0 bytes in 0 blocks
==8720== total heap usage: 6 allocs, 6 frees, 144 bytes allocated
==8720==
==8720== All heap blocks were freed -- no leaks are possible
==8720==
==8720== For counts of detected and suppressed errors, rerun with: -v
==8720== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 7)