一个单链表的实现
2009-11-29 17:44
369 查看
一.题目说明:实现一个单链表,具体要求如下:
1. 元素可以是任何类型;
2. 实现在链表末尾追加给定元素的功能,如果原链表为空,则把要追加的元素作为链表的第一个结点;
3. 将给定的元素从链表中移除;
4. 实现计算链表结点个数的功能;
5. 对单链表进行测试,数据由开发人员自行定义。
二.简要分析:
1. 数据结构:
因为数据类型要求是任何类型,根据C语言中void*与其它指针类型可以互相转换的特点,定义此单链表的数据结构如下:
typedef struct list_t{
void *data;
struct list_t *next;
} list_t;
2. 函数说明:
根据题目说明,为这个单链表提供以下三个函数:
(1) 函数原型:list_t *list_append(list_t *list, void *data)
函数功能:在链表末尾追加给定元素的功能,如果原链表为空,则把要追加的元素作为链表的第一个结点。
输入参数:list, 链表头指针
data, 要追加的数据
返回:链表头指针
(2) 函数原型list_t *list_remove(list_t *list, void *data)
函数功能:将给定的元素从链表中移除。
输入参数:list, 链表头指针
data, 要移除的数据
返回:链表头指针
(3) 函数原型:int list_getnumber(list_t *list)
函数功能:计算链表结点个数并返回。
输入参数:list, 链表头指针
返回:链表中结点的个数
3. 测试分析:
为了进行测试,定义了stu_data结构体类型,以及一个数组,用于存放测试数据。另外,写了一个函数void display_stulist(list_t *list),用于显示列表中的所有数据。具体如下:
(1)数据结构与测试数据:
typedef struct stu_data{
char ID[9];
int age;
char name[14];
} stu_data;
static stu_data stu[15][3] = {
{"69231100", 20, "zhang"},
{"69231101", 22, "wang"},
{"69231102", 21, "li"},
{"69231103", 20, "zhao"},
{"69231104", 23, "qian"},
{"69231105", 20, "sun"},
{"69231106", 20, "zhou"},
{"69231107", 21, "wu"},
{"69231108", 24, "wang"},
{"69231109", 20, "liu"},
{"69231110", 21, "liu"},
{"69231111", 22, "wang"},
{"69231112", 20, "liu"},
{"69231113", 20, "li"},
{"69231114", 23, "liu"},
};
(2)显示结果函数:
函数原型:void display_stulist(list_t *list)
函数功能:打印链表list中的所有数据,如果链表为空,则打印" list is null!"。
输入参数:list, 链表头指针
返回:无
三.详细设计:
1. list_t *list_append(list_t *list, void *data)
流程图如下:
2. list_t *list_remove(list_t *list, void *data)
流程图如下:
3. int list_getnumber(list_t *list)
流程图如下:
四.原代码
#include <stdio.h>
#include <stdlib.h>
/* list_t */
typedef struct list_t{
void *data;
struct list_t *next;
} list_t;
list_t *list_append(list_t *list, void *data)
{
list_t *entry, *prev;
entry = (list_t*)malloc(sizeof(list_t)); /* 为entry分配存储空间 */
if (!entry)
return NULL;
entry->data = data;
entry->next = NULL;
if (!list) /* 如果列表为空,则返回刚刚创建的结点 */
return entry;
for (prev = list; prev->next; prev = prev->next) ; /* 将prev指针移到列表末尾 */
prev->next = entry; /* 将新创建的结点加到列表末尾 */
return list;
}
list_t *list_remove(list_t *list, void *data)
{
list_t *entry, *prev;
for (prev = NULL, entry = list; entry; prev = entry, entry = entry->next) {
if (entry->data == data) {
if (prev)
prev->next = entry->next;
else
list = entry->next;
free(entry); /* 释放由list_append中的malloc分配的存储空间 */
break;
}
}
return list;
}
int list_getnumber(list_t *list)
{
list_t *prev;
int i=0;
if (!list)
return 0;
for (prev = list; prev->next; prev = prev->next, i++) ;
return i;
}
/* for test */
typedef struct stu_data{
char ID[9];
int age;
char name[14];
} stu_data;
static stu_data stu[15][3] = {
{"69231100", 20, "zhang"},
{"69231101", 22, "wang"},
{"69231102", 21, "li"},
{"69231103", 20, "zhao"},
{"69231104", 23, "zhang"},
{"69231105", 20, "liu"},
{"69231106", 20, "han"},
{"69231107", 21, "zhang"},
{"69231108", 24, "wang"},
{"69231109", 20, "liu"},
{"69231110", 21, "liu"},
{"69231111", 22, "wang"},
{"69231112", 20, "liu"},
{"69231113", 20, "li"},
{"69231114", 23, "liu"},
};
void display_stulist(list_t *list)
{
list_t *prev;
int i = 0;
if (!list) {
printf(" list is null!/n");
return;
}
printf("ID age name/n");
printf("----------------------------/n");
for (prev = list; prev->next; prev = prev->next,i++) {
if (i%5 == 0)
printf("/n");
printf("%s %d %s /n", (char*)((stu_data*)prev->data)->ID, ((stu_data*)prev->data)->age, (char*)((stu_data*)prev->data)->name);
}
}
void test_function(void)
{
list_t *list = NULL;
int i = 0;
/* test 1: init value of list */
printf("/ntest 1: init value of list. /n");
printf(" number of list is : %d/n",list_getnumber(list));
display_stulist(list);
/* test 2: append 9 data for list */
printf("/n/ntest 2: append 9 data for list. /n");
for (; i<10; i++) {
list = list_append(list, (void*)stu[i]);
}
printf(" number of list is : %d/n",list_getnumber(list));
display_stulist(list);
/* test 3: remove stu[5] from list. */
printf("/n/ntest 3: remove stu[5] from list./n");
list_remove(list, (void*)stu[5]);
printf(" number of list is : %d/n",list_getnumber(list));
display_stulist(list);
return;
}
int main()
{
test_function();
return 0;
}
五.函数间调用关系:
六.测试结果
1. 截图:
2. 测试结果分析:
(1) test 1 时,由于list=NULL,所以,会输出
“number of list is : 0”
“list is null!”
(2)总共测试数据有15个, 在test 2 时,向列表中追加了9个元素,并将内容打印出来,显示的个数是9。
(3)test 3 时,从列表中移除stu[5],所以,再打印列表数据时,就没有“69231105”这条记录了,而且,显示的个数是8。
1. 元素可以是任何类型;
2. 实现在链表末尾追加给定元素的功能,如果原链表为空,则把要追加的元素作为链表的第一个结点;
3. 将给定的元素从链表中移除;
4. 实现计算链表结点个数的功能;
5. 对单链表进行测试,数据由开发人员自行定义。
二.简要分析:
1. 数据结构:
因为数据类型要求是任何类型,根据C语言中void*与其它指针类型可以互相转换的特点,定义此单链表的数据结构如下:
typedef struct list_t{
void *data;
struct list_t *next;
} list_t;
2. 函数说明:
根据题目说明,为这个单链表提供以下三个函数:
(1) 函数原型:list_t *list_append(list_t *list, void *data)
函数功能:在链表末尾追加给定元素的功能,如果原链表为空,则把要追加的元素作为链表的第一个结点。
输入参数:list, 链表头指针
data, 要追加的数据
返回:链表头指针
(2) 函数原型list_t *list_remove(list_t *list, void *data)
函数功能:将给定的元素从链表中移除。
输入参数:list, 链表头指针
data, 要移除的数据
返回:链表头指针
(3) 函数原型:int list_getnumber(list_t *list)
函数功能:计算链表结点个数并返回。
输入参数:list, 链表头指针
返回:链表中结点的个数
3. 测试分析:
为了进行测试,定义了stu_data结构体类型,以及一个数组,用于存放测试数据。另外,写了一个函数void display_stulist(list_t *list),用于显示列表中的所有数据。具体如下:
(1)数据结构与测试数据:
typedef struct stu_data{
char ID[9];
int age;
char name[14];
} stu_data;
static stu_data stu[15][3] = {
{"69231100", 20, "zhang"},
{"69231101", 22, "wang"},
{"69231102", 21, "li"},
{"69231103", 20, "zhao"},
{"69231104", 23, "qian"},
{"69231105", 20, "sun"},
{"69231106", 20, "zhou"},
{"69231107", 21, "wu"},
{"69231108", 24, "wang"},
{"69231109", 20, "liu"},
{"69231110", 21, "liu"},
{"69231111", 22, "wang"},
{"69231112", 20, "liu"},
{"69231113", 20, "li"},
{"69231114", 23, "liu"},
};
(2)显示结果函数:
函数原型:void display_stulist(list_t *list)
函数功能:打印链表list中的所有数据,如果链表为空,则打印" list is null!"。
输入参数:list, 链表头指针
返回:无
三.详细设计:
1. list_t *list_append(list_t *list, void *data)
流程图如下:
2. list_t *list_remove(list_t *list, void *data)
流程图如下:
3. int list_getnumber(list_t *list)
流程图如下:
四.原代码
#include <stdio.h>
#include <stdlib.h>
/* list_t */
typedef struct list_t{
void *data;
struct list_t *next;
} list_t;
list_t *list_append(list_t *list, void *data)
{
list_t *entry, *prev;
entry = (list_t*)malloc(sizeof(list_t)); /* 为entry分配存储空间 */
if (!entry)
return NULL;
entry->data = data;
entry->next = NULL;
if (!list) /* 如果列表为空,则返回刚刚创建的结点 */
return entry;
for (prev = list; prev->next; prev = prev->next) ; /* 将prev指针移到列表末尾 */
prev->next = entry; /* 将新创建的结点加到列表末尾 */
return list;
}
list_t *list_remove(list_t *list, void *data)
{
list_t *entry, *prev;
for (prev = NULL, entry = list; entry; prev = entry, entry = entry->next) {
if (entry->data == data) {
if (prev)
prev->next = entry->next;
else
list = entry->next;
free(entry); /* 释放由list_append中的malloc分配的存储空间 */
break;
}
}
return list;
}
int list_getnumber(list_t *list)
{
list_t *prev;
int i=0;
if (!list)
return 0;
for (prev = list; prev->next; prev = prev->next, i++) ;
return i;
}
/* for test */
typedef struct stu_data{
char ID[9];
int age;
char name[14];
} stu_data;
static stu_data stu[15][3] = {
{"69231100", 20, "zhang"},
{"69231101", 22, "wang"},
{"69231102", 21, "li"},
{"69231103", 20, "zhao"},
{"69231104", 23, "zhang"},
{"69231105", 20, "liu"},
{"69231106", 20, "han"},
{"69231107", 21, "zhang"},
{"69231108", 24, "wang"},
{"69231109", 20, "liu"},
{"69231110", 21, "liu"},
{"69231111", 22, "wang"},
{"69231112", 20, "liu"},
{"69231113", 20, "li"},
{"69231114", 23, "liu"},
};
void display_stulist(list_t *list)
{
list_t *prev;
int i = 0;
if (!list) {
printf(" list is null!/n");
return;
}
printf("ID age name/n");
printf("----------------------------/n");
for (prev = list; prev->next; prev = prev->next,i++) {
if (i%5 == 0)
printf("/n");
printf("%s %d %s /n", (char*)((stu_data*)prev->data)->ID, ((stu_data*)prev->data)->age, (char*)((stu_data*)prev->data)->name);
}
}
void test_function(void)
{
list_t *list = NULL;
int i = 0;
/* test 1: init value of list */
printf("/ntest 1: init value of list. /n");
printf(" number of list is : %d/n",list_getnumber(list));
display_stulist(list);
/* test 2: append 9 data for list */
printf("/n/ntest 2: append 9 data for list. /n");
for (; i<10; i++) {
list = list_append(list, (void*)stu[i]);
}
printf(" number of list is : %d/n",list_getnumber(list));
display_stulist(list);
/* test 3: remove stu[5] from list. */
printf("/n/ntest 3: remove stu[5] from list./n");
list_remove(list, (void*)stu[5]);
printf(" number of list is : %d/n",list_getnumber(list));
display_stulist(list);
return;
}
int main()
{
test_function();
return 0;
}
五.函数间调用关系:
六.测试结果
1. 截图:
2. 测试结果分析:
(1) test 1 时,由于list=NULL,所以,会输出
“number of list is : 0”
“list is null!”
(2)总共测试数据有15个, 在test 2 时,向列表中追加了9个元素,并将内容打印出来,显示的个数是9。
(3)test 3 时,从列表中移除stu[5],所以,再打印列表数据时,就没有“69231105”这条记录了,而且,显示的个数是8。
相关文章推荐
- 关于栈的一个算法(实现单链表的倒置)
- c语言又一个单链表的实现
- 编写一个程序,实现单链表的各种基本运算
- python实现一个单链表
- C语言一个单链表的实现
- 009实现一个算法来删除单链表中的一个结点,仅仅给出指向那个结点的指针(keep it up)
- 编写查找一个单链表特定元素的程序。分别使用递归和非递归方法实现,并比较它们的运行时间。
- 反转一个单链表的循环和递归实现
- 一个链表的每个节点,有一个指向next指针指向下一个节点,还有一个rand指针指向这个链表中的一个随机节点或NULL,现在要求复制一个单链表来实现这个链表,返回复制后的新链表。
- 反转一个单链表的循环和递归实现
- 2.2 实现一个算法从一个单链表中返回倒数第n个元素
- 本题要求实现一个函数,求单链表L结点的阶乘和
- 【Java】实现一个算法,找出一个单链表中倒数第K个结点
- 编程实现一个单链表的查找
- 写代码,反转一个单链表,分别以迭代和递归的形式来实现
- 用php实现一个单链表
- 输入一组整型元素序列,使用尾插法建立一个带有头结点的单链表。 ② 实现该线性表的遍历。 ③ 在该单链表的第i个元素前插入一个整数。 ④ 删除该单链表中的第i个元素,其值通过参数将其返回。 ⑤ 建立两个
- 单链表实现一个随机队列
- 基础笔试题:编程实现一个单链表的建立、测长、打印
- 问题9:编程实现一个单链表的建立/测长/打印以及结点的删除。