当前位置:首页 > C语言
线性表之顺序存储实验
来源:靑龍一笑的博客  作者:靑龍一笑  发布时间:2022-10-04 10:59:31  点击量:139  评论:0

    线性表是最基本最常用的数据结构,常用的存储方式有两种:顺序存储和链式存储。
    顺序表的实现如下:

1、seqlist.h 文件

/*
 * 线性表的顺序存储结构(顺序表)
 */
#ifndef SEQLIST_H__
#define SEQLIST_H__

// 宏定义
#define DATASIZE 1024

// 顺序表元素类型定义
typedef int datatype;

/*
 * 顺序表结构
 * 使用定长数组来存储数据元素
 */
typedef struct node_st {
    datatype data[DATASIZE];
    int last; // 用来保存当前存放最后一个元素的位置
}seqlist;

/*
 * 初始化,创建顺序表
 * 返回结构体类型的指针
 */
seqlist *seqlist_create();

/*
 * 初始化,创建顺序表
 * 传入一个二级指针的方式
 */
void seqlist_init(seqlist **);

/*
 * 销毁顺序表
 * 释放顺序表所占内存
 */
void seqlist_destroy(seqlist *);

/*
 * 判断顺序表是否为空
 */
int seqlist_is_empty(seqlist *);

/*
 * 顺序表置空
 */
void seqlist_set_empty(seqlist *);

/*
 * 获取顺序表中元素的个数
 */
int seqlist_length(seqlist *);

/*
 * 从顺序表中查找数据
 */
int seqlist_find(seqlist *, datatype *);

/*
 * 往顺序表中插入数据
 */
int seqlist_insert(seqlist *, int, datatype *);

/*
 * 从顺序表中删除数据
 */
int seqlist_delete(seqlist *, int);

/*
 * 遍历顺序表
 */
void seqlist_display(seqlist *);

/*
 * 合并两个顺序表
 */
void seqlist_union(seqlist *, seqlist *);

#endif

2、seqlish.c 文件

#include <stdio.h>
#include <stdlib.h>

#include "seqlist.h"

/*
 * 初始化,创建顺序表
 * 返回结构体类型的指针
 */
seqlist *seqlist_create() {
    seqlist *ptr;
    ptr = malloc(sizeof(*ptr));
    if (ptr == NULL) {
        return NULL;
    }

    // 刚初始化的顺序表没有元素
    ptr->last = -1;
    return ptr;
}

/*
 * 初始化,创建顺序表
 * 传入一个二级指针的方式
 */
void seqlist_init(seqlist **ptr) {
    *ptr = malloc(sizeof(**ptr));
    if (*ptr == NULL) {
        return; // 无返回值
    }

    // 刚初始化的顺序表没有元素
    (*ptr)->last = -1;
    return; // 无返回值
}

/*
 * 销毁顺序表
 * 释放顺序表所占内存
 */
void seqlist_destroy(seqlist *ptr) {
    // 释放顺序表内存
    free(ptr);
    // 释放内存后指针置空
    ptr = NULL;

    return; // 无返回值
}

/*
 * 判断顺序表是否为空
 */
int seqlist_is_empty(seqlist *ptr) {
    if (ptr->last == -1) {
        // 顺序表为空
        return 0;
    }

    // 非空
    return -1;
}

/*
 * 顺序表置空
 */
void seqlist_set_empty(seqlist *ptr) {
    ptr->last = -1;
    return; // 无返回值
}

/*
 * 获取顺序表中元素的个数
 */
int seqlist_length(seqlist *ptr) {
    /*
     * 当 last 为 -1 时,表示顺序表为空
     * 当 last 为 0 时,表示顺序表中有一个元素
     * 因此,顺序表中元素的个数为 last + 1
     */
    return (ptr->last + 1);
}

/*
 * 从顺序表中查找数据
 */
int seqlist_find(seqlist *ptr, datatype *data) {
    int i; // 循环索引值
    if (seqlist_is_empty(ptr) == 0) {
        // 顺序表为空
        return -2;
    }

    for (i = 0; i <= ptr->last; i++) {
        if (ptr->data[i] == *data) {
            // 返回元素所在位置
            return i;
        }
    }

    // 没有找到
    return -1;
}

/*
 * 往顺序表中插入数据
 */
int seqlist_insert(seqlist *ptr, int pos, datatype *data) {
    int i; // 循环索引值
    if (ptr->last == DATASIZE - 1) {
        // 空间满了
        return -1;
    }

    if (pos < 0 || pos > ptr->last + 1) {
        // 插入的位置不对
        return -2;
    }

    for (i = ptr->last; pos <= i; i--) {
        // 要插入位置上的元素,及其之后的元素,依次后移一位
        ptr->data[i+1] = ptr->data[i];
    }
    // 插入数据
    ptr->data[pos] = *data;
    ptr->last++;

    // 成功插入
    return 0;
}

/*
 * 从顺序表中删除数据
 */
int seqlist_delete(seqlist *ptr, int pos) {
    int i; // 循环索引值
    if (pos < 0 || pos > ptr->last) {
        // 删除元素的位置不对
        return -1;
    }

    for (i = pos + 1; i <= ptr->last; i++) {
        // 要删除元素的位置后的所有元素依次前移一位
        ptr->data[i-1] = ptr->data[i];
    }
    ptr->last--;

    // 删除成功
    return 0;
}

/*
 * 遍历顺序表
 */
void seqlist_display(seqlist *ptr) {
    int i; // 循环索引值
    if (seqlist_is_empty(ptr) == 0) {
        // 顺序表为空
        return; // 无返回值
    }

    for (i = 0; i <= ptr->last; i++) {
        printf("%d ", ptr->data[i]);
    }
    printf("\n");

    return; // 无返回值
}

/*
 * 合并两个顺序表
 * 将 list2 中的所有元素合并到 list1 中
 * 合并时去除重复数据
 */
void seqlist_union(seqlist *list1, seqlist *list2) {
    int i; // 循环索引值
    for (i = 0; i <= list2->last; i++) {
        if (seqlist_find(list1, &list2->data[i]) < 0) {
            // 去重追加插入
            seqlist_insert(list1, list1->last+1, &list2->data[i]);
        }
    }
}

3、main.c 文件

#include <stdio.h>
#include <stdlib.h>

#include "seqlist.h"

int main() {
    int i; // 循环索引值
    int ret; // 返回状态值
    seqlist *list1 = NULL, *list2 = NULL; // 两个顺序表
    // 两条测试数据
    datatype data1[] = {63, 89, 95, 76, 57, 31};
    datatype data2[] = {49, 76, 63, 81, 35, 24};
    // 查找的数据
    int search_data = 95;

    /* 初始化顺序表 */
    // 采用不同的方式初始化两个顺序表
    list1 = seqlist_create();
    if (list1 == NULL) {
        fprintf(stderr, "初始化顺序表 list1 失败!\n");
        exit(1);
    }

    seqlist_init(&list2);
    if (list2 == NULL) {
        fprintf(stderr, "初始化顺序表 list2 失败!\n");
        exit(1);
    }

    /* 往顺序表中插入数据 */
    for (i = 0; i < sizeof(data1)/sizeof(*data1); i++) {
        // 往顺序表 list1 中插入 data1 数据
        if ((ret = seqlist_insert(list1, list1->last + 1, &data1[i])) != 0) {
            if (ret == -1) {
                fprintf(stderr, "顺序表 list1 空间满了。\n");
            } else if (ret == -2) {
                fprintf(stderr, "顺序表 list1 数据插入位置有误。\n");
            } else {
                fprintf(stderr, "发生未知错误。\n");
            }
            exit(1);
        }
    }

    for (i = 0; i < sizeof(data2)/sizeof(*data2); i++) {
        // 往顺序表 list2 中插入 data2 数据
        if ((ret = seqlist_insert(list2, list2->last + 1, &data2[i])) != 0) {
            if (ret == -1) {
                fprintf(stderr, "顺序表 list2 空间满了。\n");
            } else if (ret == -2) {
                fprintf(stderr, "顺序表 list2 数据插入的位置有误。\n");
            } else {
                fprintf(stderr, "发生未知错误。\n");
            }
            exit(1);
        }
    }

    /* 遍历顺序表 */
    printf("顺序表 list1 中的元素:");
    seqlist_display(list1);
    printf("顺序表 list2 中的元素:");
    seqlist_display(list2);

    /* 顺序表置空 */
    //seqlist_set_empty(list1);

    /* 从顺序表中查找数据 */
    ret = seqlist_find(list1, &search_data);
    if (ret == -2) {
        printf("顺序表 list1 为空。\n");
    } else if (ret == -1) {
        printf("在顺序表 list1 中没有找到 %d\n", search_data);
    } else {
        printf("%d 在顺序表 list1 中的索引值:%d\n", search_data, ret);
    }

    /* 从顺序表中删除数据 */
    if ((ret = seqlist_delete(list1, 2)) != 0) {
        if (ret == -1) {
            fprintf(stderr, "从顺序表 list1 中删除元素的位置有误。\n");
        } else {
            fprintf(stderr, "发生未知错误。\n");
        }
        exit(1);
    }

    /* 合并两个顺序表 */
    seqlist_union(list1, list2);

    /* 获取顺序表中元素的个数 */
    printf("顺序表 list1 中元素的个数:%d\n", seqlist_length(list1));
    printf("顺序表 list2 中元素的个数:%d\n", seqlist_length(list2));

    /* 遍历顺序表 */
    printf("顺序表 list1 中的元素:");
    seqlist_display(list1);
    printf("顺序表 list2 中的元素:");
    seqlist_display(list2);

    /* 销毁顺序表 */
    seqlist_destroy(list1);
    seqlist_destroy(list2);
}

4、Makefile 文件

OBJS=main.o seqlist.o
CC=gcc
CFLAGS+=-c -Wall -g
seqlist:$(OBJS)
    $(CC) $^ -o $@
%.o:%.c
    $(CC) $^ $(CFLAGS) -o $@
clean:
    $(RM) *.o seqlist -r

    执行效果:

root@RicenOS:~# make
gcc main.c -c -Wall -g -o main.o
gcc seqlist.c -c -Wall -g -o seqlist.o
gcc main.o seqlist.o -o seqlist
root@RicenOS:~# ./seqlist
顺序表 list1 中的元素:63 89 95 76 57 31
顺序表 list2 中的元素:49 76 63 81 35 24
95 在顺序表 list1 中的索引值:2
顺序表 list1 中元素的个数:9
顺序表 list2 中元素的个数:6
顺序表 list1 中的元素:63 89 76 57 31 49 81 35 24
顺序表 list2 中的元素:49 76 63 81 35 24
版权所有 © 2005-2023 靑龍一笑的博客  Powered by C.S.Ricen
Copyright © 2005-2023 by www.ricensoftwares.com.cn  All Rights Reserved.

欢迎光临本站,这里是靑龍一笑的博客。

因资金匮乏,本站已迁到国外的免费空间,可能导致本站的访问速度较慢,由此给您带来的不便,敬请谅解。

您可以通过下方的“支持本站建设”链接,给本站提供资金支持。

Free Web Hosting