题目
1. 单链表的插入和删除 :要求单链表的数据域是字符串,完成单链表的初始化、插入、删除操作,插入时不允许重复的串插入表中。
文件布局:
PS D:\code\gongda\datastruct\data_2_1> tree /f
卷 软件 的文件夹 PATH 列表
卷序列号为 0007-DC50
D:.
│ .cproject
│ .project
│ Makefile
│
├─include
│ list.h
│
└─src
list.c
Main.c
PS D:\code\gongda\datastruct\data_2_1>
list.h
单链表结构及操作定义
/** @file list.h
* 功能:辽工大之该死的数据结构之报告之一:单链表的操作
* 时间:2015年1月11日18:56:53
* 作者:小代码
*/
#ifndef INCLUDE_LIST_H_
#define INCLUDE_LIST_H_
/** @struct 单链表结构定义
*
*/
struct _list{
/** 数据域 */
char str[20];
/** 指针域 */
struct _list * next;
};
typedef struct _list list;
typedef struct _list * listPtr;
/** @brief 链表的初始化
*
* @return
*/
listPtr list_init();
/** @brief 链表的插入
* 尾插法
*
* @param l 要插入元素的单链表
* @param str 要插入的元素的字符串
*
* @pre 链表 l 存在 且字符串 str 不存在于链表中
*
* @retval 0 插入成功
* @retval 1 插入失败
*
*/
int list_append( listPtr l , char str[20]);
/** @brief 链表的删除
*
* @param l 要删除元素的链表
* @param str 要删除的结点的字符串
*
* @pre 链表 l 存在 且字符串 str 存在于链表中
*
* @retval 0 删除成功
* @retval 1 删除失败,字符串str不存在于链表中
* @retval -1 链表 l 不存在 或链表为空
*/
int list_delete( listPtr l, char str[20]);
/** @brief 检测字符串 str 是否存在于链表l 中
*
* @param l 链表
* @param str 要检测的字符串
*
* @pre 链表 l 存在且不为空
*
* @retval 0 存在
* @retval 1 不存在
* @retval -1 链表不存在或链表为空
*/
int list_has_str( listPtr l, char str[20] );
/** @brief 检测链表是否为空
*
* @param l 链表
*
* @pre 链表 l 存在
*
* @retval 0 链表为空
* @retval 1 链表不为空
* @retval -1 链表不存在
*/
int list_is_empty( listPtr l );
/** @brief 输出链表
*
* @param l 要输出的链表
*
* @pre 链表 l 存在
*
* @retval 0 输出成功
* @retval 1 链表为空
* @retval -1 链表不存在
*
*/
int list_print( listPtr l );
/** @brief 销毁链表
*
* @param l 要销毁的链表
*
* @pre 链表 l 存在
*
* @retval 0 销毁成功
* @retval 1 销毁失败
*/
int list_destroy( listPtr l );
#endif /* INCLUDE_LIST_H_ */
list.c
单链表操作实现
/*
* list.c
*
* Created on: 2015年1月11日
* Author: laolang
*/
#include"../include/list.h"
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
/** @brief 链表的初始化
*
* @return
*/
listPtr list_init() {
listPtr l = (listPtr) malloc(sizeof(list));
if ( NULL == l) {
puts("动态分配内存失败!list_init...l");
exit(-1);
}
l->next = NULL;
return l;
}
/** @brief 链表的插入
* 尾插法
*
* @param l 要插入元素的单链表
* @param str 要插入的元素的字符串
*
* @pre 链表 l 存在 且字符串 str 不存在于链表中
*
* @retval 0 插入成功
* @retval 1 插入失败
*
*/
int list_append(listPtr l, char str[20]) {
int result = 0;
if (!list_has_str(l, str)) {
printf("字符串:\"%s\"已存在于链表中\n",str);
result = 1;
} else {
listPtr p = l;
listPtr newData = (listPtr) malloc(sizeof(list));
newData->next = NULL;
strcpy(newData->str, str);
while ( NULL != p->next) {
p = p->next;
}
p->next = newData;
}
return result;
}
/** @brief 链表的删除
*
* @param l 要删除元素的链表
* @param str 要删除的结点的字符串
*
* @pre 链表 l 存在 且字符串 str 存在于链表中
*
* @retval 0 删除成功
* @retval 1 删除失败,字符串str不存在于链表中
* @retval -1 链表 l 不存在 或链表为空
*/
int list_delete(listPtr l, char str[20]) {
int result = 0;
if ( NULL == l || !list_is_empty(l)) {
result = -1;
} else {
listPtr p = l;
listPtr deleteP = NULL;
while ( NULL != p->next) {
if (!strcmp(p->next->str, str)) {
deleteP = p;
break;
}
p = p->next;
}
if ( NULL != deleteP) {
p->next = p->next->next;
free(deleteP);
} else {
result = 1;
}
}
return result;
}
/** @brief 检测字符串 str 是否存在于链表l 中
*
* @param l 链表
* @param str 要检测的字符串
*
* @pre 链表 l 存在且不为空
*
* @retval 0 存在
* @retval 1 不存在
* @retval -1 链表不存在或链表为空
*/
int list_has_str(listPtr l, char str[20]) {
int result = 1;
if ( NULL == l || !list_is_empty(l)) {
result = -1;
} else {
listPtr p = l->next;
while ( NULL != p) {
if (!strcmp(p->str, str)) {
result = 0;
break;
}
p = p->next;
}
}
return result;
}
/** @brief 检测链表是否为空
*
* @param l 链表
*
* @pre 链表 l 存在
*
* @retval 0 链表为空
* @retval 1 链表不为空
* @retval -1 链表不存在
*/
int list_is_empty(listPtr l) {
int result = 0;
if ( NULL == l) {
puts("链表不存在");
result = -1;
}
if ( NULL != l->next) {
result = 1;
}
return result;
}
/** @brief 输出链表
*
* @param l 要输出的链表
*
* @pre 链表 l 存在
*
* @retval 0 输出成功
* @retval 1 链表为空
* @retval -1 链表不存在
*
*/
int list_print(listPtr l) {
int result = 0;
if ( NULL == l) {
result = -1;
} else {
if (!list_is_empty(l)) {
result = 1;
} else {
listPtr p = l->next;
while ( NULL != p) {
printf("%s\n", p->str);
p = p->next;
}
}
}
return result;
}
/** @brief 销毁链表
*
* @param l 要销毁的链表
*
* @pre 链表 l 存在
*
* @retval 0 销毁成功
* @retval 1 销毁失败
*/
int list_destroy( listPtr l ){
int result = 0;
if( NULL == l ){
result = 1;
}else{
listPtr p = l->next;
while( NULL != p ){
listPtr t = p;
p = p->next;
free(t);
}
free(p);
}
return result;
}
Main.c
主文件
/*
* Main.c
*
* Created on: 2015年1月11日
* Author: laolang
*/
#include"../include/list.h"
#include<stdio.h>
int main(void) {
listPtr head = list_init();
list_append(head,"小代码");
//添加重复的字符串
list_append(head,"小代码");
list_append(head,"老狼");
list_append(head,"陈");
list_append(head,"李");
//输出链表
list_print(head);
//删除链表中字符串为 小代码 的结点
list_delete(head,"小代码");
puts("删除字符串为:\"小代码\"的结点之后的链表");
//输出链表
list_print(head);
if( !list_destroy(head)){
puts("链表已销毁");
}
return 0;
}
Makefile
# 功能:工大数据结构报告一:单链表操作
#
# 时间:2015年1月11日19:32:07
#
# 作者:小代码
#
#
#
#
program=test.exe
CC=gcc
CFLAGS=-Wall -I include
RM=del
vpath %.h include
vpath %.c src
DIR:=$(wildcard *.c ./src/*.c)
SOURS:=$(notdir $(DIR))
OBJS:=$(patsubst %.c,%.o,$(SOURS))
all:$(program)
$(program):$(OBJS)
$(CC) -o $@ $^
Main.o:list.h
list.o:list.h
.PHNOY:clean run list
clean:
-$(RM) $(OBJS) $(program)
run: $(program)
./$(program)
list:
@echo $(DIR)
@echo $(SOURS)
@echo $(OBJS)
运行效果
PS D:\code\gongda\datastruct\data_2_1> make run
gcc -Wall -I include -c -o Main.o src/Main.c
gcc -Wall -I include -c -o list.o src/list.c
gcc -o test.exe Main.o list.o
./test.exe
字符串:"小代码"已存在于链表中
小代码
老狼
陈
李
删除字符串为:"小代码"的结点之后的链表
老狼
陈
李
链表已销毁
PS D:\code\gongda\datastruct\data_2_1>