并实现相应的操作。包括:初始化
/
空间释放
/
增加结点
/
查找
/
删除
/
遍历打印
/
排序。
代码中的 data_t 类型也可用结构体封装的复杂类型代替。
代码中的 data_t 类型也可用结构体封装的复杂类型代替。
代码如下,共3个文件,分别为头文件<single.h>,函数实现<single.c>,测试程序<test.c>
<single.h>
/* ***************************************************
* Name: single.h
* Desc: 单向链式存储线性表相关操作的实现, 包括:
* 初始化/空间释放/增加结点/查找/删除/遍历打印/排序
* **************************************************/
#ifndef _SINGLE_H_
#define _SINGLE_H_
#include <stdbool.h>
typedef int data_t; /* 用户自定义数据类型 */
struct node { /* 单链表结点 */
data_t data; /* 数据存储区域 */
struct node *next; /* 后继链表指针 */
};
struct link {
struct node head; /* 链表头 */
int nsize; /* 链表结点大小 */
int num; /* 记录当前结点数量 */
};
void link_init(struct link *l);
void link_release(struct link *l);
int link_add(struct link *l, data_t *data);
struct node *link_prev(struct link *l, struct node *n);
struct node *link_find(struct link *l, int cmp(struct node *n, void *key), void *key);
void link_del(struct link *l, struct node *n);
void link_qdel(struct link *l, struct node *n);
void link_print(struct link *l);
void link_sort(struct link *l, int cmp(void *a, void *b));
#endif
<single.c>
/* ***************************************************
* Name: single.c
* Desc: 单向链式存储线性表相关操作的实现, 包括:
* 初始化/空间释放/增加结点/查找/删除/遍历打印/排序
* Author: Joshua Chan
* Date: 2011-11-1
* **************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "single.h"
/* 结构初始化, 包括链表头初始化 */
void link_init(struct link *l)
{
l->nsize = sizeof(struct node);
l->num = 0;
l->head.next = NULL;
}
/* 数据存储空间释放 */
void link_release(struct link *l)
{
struct node *cur, *save;
for (cur = l->head.next; cur != NULL; cur = save) {
save = cur->next;
free(cur);
}
l->num = 0;
l->head.next = NULL;
}
/* 结点增加 */
int link_add(struct link *l, data_t *data)
{
struct node *new;
if ((new = malloc(l->nsize)) == NULL)
return -1;
new->data = *data;
new->next = l->head.next;
l->head.next = new;
l->num++;
return 0;
}
/* 定位前一个结点 */
struct node *link_prev(struct link *l, struct node *n)
{
struct node *cur;
cur = l->head.next;
if (cur == n) /* 判数n是否为第一个结点 */
return &l->head;
while (cur->next != n)
cur = cur->next;
return cur;
}
/* 根据给定条件查找结点 */
struct node *link_find(struct link *l, int cmp(struct node *n, void *key), void *key)
{
struct node *cur;
for (cur = l->head.next; cur != NULL; cur = cur->next)
if (cmp(cur, key) == 0)
return cur;
return cur;
}
/* 删除结点 */
void link_del(struct link *l, struct node *n)
{
struct node *prev;
prev = link_prev(l, n);
prev->next = n->next;
n->next = NULL;
free(n);
l->num--;
}
/* 遍历打印数据 */
void link_print(struct link *l)
{
struct node *cur;
for (cur = l->head.next; cur != NULL; cur = cur->next)
printf("%d ", cur->data);
putchar('\n');
}
/* 结点换位 */
static inline void swap(struct node *a, struct node *b)
{
data_t tmp;
tmp = a->data;
a->data = b->data;
b->data = tmp;
}
/* 根据给定条件对链表排序 */
void link_sort(struct link *l, int cmp(void *a, void *b))
{
int i, j;
struct node *cur, *next;
bool flag;
for (i = 0; i < l->num; i++) {
cur = l->head.next;
next = NULL;
flag = true;
for (j = 0; j < l->num - i - 1; j++) {
next = cur->next;
if (cmp(&cur->data, &next->data) > 0) {
swap(cur, next);
flag = false;
}
cur = next;
}
if (flag == true)
break;
}
}
<test.c>
/* ***************************************************
* Name: test.c
* Desc: 单向链式存储线性表相关操作的测试程序
* Author: Joshua Chan
* Date: 2011-11-1
* **************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "single.h"
/* 查找比较函数 */
int cmp_find(struct node *n, void *key)
{
return (n->data == *(data_t *)key) ? 0 : -1;
}
/* 排序比较函数 */
int cmp_sort(void *a, void *b)
{
if (*(data_t *)a > *(data_t *)b)
return 1;
else if (*(data_t *)a < *(data_t *)b)
return -1;
else
return 0;
}
void put_data(data_t *data, int n)
{
*data = n;
}
int main(void)
{
int i;
struct link l;
struct node *n;
data_t data;
/* 单链表初始化 */
link_init(&l);
srand(time(NULL));
/* 以随机数填充 */
for (i = 0; i < 10; i++) {
put_data(&data, rand() % 10);
link_add(&l, &data);
}
link_print(&l);
i = 3;
/* 查找给定数据并删除相应结点 */
if ((n = link_find(&l, cmp_find, &i)) != NULL) {
//link_del(&l, n);
link_del(&l, n);
printf("%d was found and deleted\n", i);
link_print(&l);
} else
printf("%d was not found\n", i);
/* 对链表排序 */
link_sort(&l, cmp_sort);
printf("data was sorted\n");
link_print(&l);
link_release(&l);
return 0;
}