二.单向链式存储线性表

并实现相应的操作。包括:初始化 / 空间释放 / 增加结点 / 查找 / 删除 / 遍历打印 / 排序。
  代码中的 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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值