数据结构之线性表

#include <stdio.h>
#include <malloc.h>

#define LIST_MAX_LENGTH 10

// 整型的线性表。关键是数据。
typedef struct SequentialList {
    int actualLength;

    int data[LIST_MAX_LENGTH]; // 最大长度是固定的。
} *SequentialListPtr;


 // 输出列表。
void outputList(SequentialListPtr paraList) {
    for (int i = 0; i < paraList->actualLength; i++) {
        printf("%d ", paraList->data[i]);
    }
    printf("\r\n");
}

//输出列表的内存。
void outputMemory(SequentialListPtr paraListPtr) {
    printf("结构体的地址: %ld\r\n", paraListPtr);
    printf("actualLength的地址: %ld\r\n", &paraListPtr->actualLength);
    printf("data的地址: %ld\r\n", &paraListPtr->data);
    printf("实际数据的地址: %ld\r\n", &paraListPtr->data[0]);
    printf("第二个数据的地址: %ld\r\n", &paraListPtr->data[1]);
}

/**
 * 初始化一个顺序列表。这个函数不进行错误检查。
 * @param paraListPtr 列表的指针。它必须是一个指针以便可以改变列表。
 * @param paraValues 一个存储所有元素的int数组的长度
 */
SequentialListPtr sequentialListInit(int paraData[], int paraLength) {
    SequentialListPtr resultPtr = (SequentialListPtr)malloc(sizeof(struct SequentialList));
    for (int i = 0; i < paraLength; i++) {
        resultPtr->data[i] = paraData[i];
    }
    resultPtr->actualLength = paraLength;

    return resultPtr;
}

/**
 * 在顺序线性列表中插入一个元素。
 * @param paraListPtr 列表的指针。它必须是一个指针以便可以改变列表。
 * @param paraPosition 位置,例如,0代表在第一个位置插入。
 * @param paraValue 要插入的值。
 */
void sequentialListInsert(SequentialListPtr paraListPtr, int paraPosition, int paraValue) {
    // 第1步。空间检查。
    if (paraListPtr->actualLength >= LIST_MAX_LENGTH) {
        printf("无法插入元素:列表已满。\r\n");
        return;
    }//Of if

    // 第2步。位置检查。
    if (paraPosition < 0) {
        printf("无法插入元素:不支持负位置。");
        return;
    }//Of if
    if (paraPosition > paraListPtr->actualLength) {
        printf("无法插入元素:位置 %d 大于列表长度 %d。\r\n", paraPosition, paraListPtr->actualLength);
        return;
    }//Of if

    // 第3步。移动剩余部分。
    for (int i = paraListPtr->actualLength; i > paraPosition; i--) {
        paraListPtr->data[i] = paraListPtr->data[i - 1];
    }//Of for i

    // 第4步。插入。
    paraListPtr->data[paraPosition] = paraValue;

    // 第5步。更新长度。
    paraListPtr->actualLength++;
}// Of sequentialListInsert

//测试插入功能。
void sequentialInsertTest() {
    int i;
    int tempArray[5] = { 3, 5, 2, 7, 4 };

    printf("---- sequentialInsertTest 开始。 ----\r\n");

    // 初始化。
    SequentialListPtr tempList = sequentialListInit(tempArray, 5);
    printf("初始化后,列表是:");
    outputList(tempList);

    // 插入到第一个。
    printf("现在插入到第一个,列表是:");
    sequentialListInsert(tempList, 0, 8);
    outputList(tempList);

    // 插入到最后。
    printf("现在插入到最后,列表是:");
    sequentialListInsert(tempList, 6, 9);
    outputList(tempList);

    // 插入到尾部之外。
    printf("现在插入到尾部之外。 \r\n");
    sequentialListInsert(tempList, 8, 9);
    printf("列表是:");
    outputList(tempList);

    // 插入到位置3。
    for (i = 0; i < 5; i++) {
        printf("正在插入 %d。\r\n", (i + 10));
        sequentialListInsert(tempList, 0, (i + 10));
        outputList(tempList);
    }//Of for i

    printf("---- sequentialInsertTest 结束。 ----\r\n");
}// Of sequentialInsertTest

/**
 * 从顺序线性列表中删除一个元素。
 * @param paraListPtr 列表的指针。它必须是一个指针以便可以改变列表。
 * @param paraPosition 位置,例如,0代表在第一个位置删除。
 * @return 被删除的值。
 */
int sequentialListDelete(SequentialListPtr paraListPtr, int paraPosition) {
    // 第1步。位置检查。
    if (paraPosition < 0) {
        printf("无效位置:%d。\r\n", paraPosition);
        return -1;
    }//Of if

    if (paraPosition >= paraListPtr->actualLength) {
        printf("无法删除元素:位置 %d 超出了列表长度 %d。\r\n", paraPosition, paraListPtr->actualLength);
        return -1;
    }//Of if

    // 第2步。移动剩余部分。
    int resultValue = paraListPtr->data[paraPosition];
    for (int i = paraPosition; i < paraListPtr->actualLength - 1; i++) {
        paraListPtr->data[i] = paraListPtr->data[i + 1];
    }//Of for i

    // 第3步。更新长度。
    paraListPtr->actualLength--;

    // 第4步。返回值。
    return resultValue;
}// Of sequentialListDelete

//测试删除功能。
void sequentialDeleteTest() {
    int tempArray[5] = { 3, 5, 2, 7, 4 };

    printf("---- sequentialDeleteTest 开始。 ----\r\n");

    // 初始化。
    SequentialListPtr tempList = sequentialListInit(tempArray, 5);
    printf("初始化后,列表是:");
    outputList(tempList);

    // 删除第一个。
    printf("现在删除第一个,列表是:");
    sequentialListDelete(tempList, 0);
    outputList(tempList);

    // 删除最后一个。
    printf("现在删除最后一个,列表是:");
    sequentialListDelete(tempList, 3);
    outputList(tempList);

    // 删除第二个。
    printf("现在删除第二个,列表是:");
    sequentialListDelete(tempList, 1);
    outputList(tempList);

    // 尝试删除第5个。
    printf("现在删除第5个,列表是:");
    sequentialListDelete(tempList, 5);
    outputList(tempList);

    // 尝试删除第-6个。
    printf("现在删除第-6个,列表是:");
    sequentialListDelete(tempList, -6);
    outputList(tempList);

    printf("---- sequentialDeleteTest 结束。 ----\r\n");

    outputMemory(tempList);
}// Of sequentialDeleteTest

/**
 * 定位列表中的一个元素。
 * @param paraListPtr 列表的指针。
 * @param paraValue 指定的值。
 * @return 值的位置,或者 -1 表示不存在
 */
int locateElement(SequentialListPtr paraListPtr, int paraValue) {
    for (int i = 0; i < paraListPtr->actualLength; i++) {
        if (paraListPtr->data[i] == paraValue) {
            return i;
        }// Of if
    }//Of for i

    return -1;
}// Of locateElement

/**
 * 获取列表中的一个元素。
 * @param paraListPtr 列表的指针。
 * @param paraPosition 给定的位置。
 * @return 位置的值,或者 -1 表示不存在
 */
int getElement(SequentialListPtr paraListPtr, int paraPosition) {
    // 第1步。位置检查。
    if (paraPosition < 0) {
        printf("无效位置:%d。\r\n", paraPosition);
        return -1;
    }//Of if

    if (paraPosition >= paraListPtr->actualLength) {
        printf("无法获取元素:位置 %d 超出了列表长度 %d。\r\n", paraPosition, paraListPtr->actualLength);
        return -1;
    }//Of if

    return paraListPtr->data[paraPosition];
}// Of getElement

/**
 * 清除列表中的元素。
 * @param paraListPtr 列表的指针。
 */
void clearList(SequentialListPtr paraListPtr) {
    paraListPtr->actualLength = 0;
}// Of clearList

//主程序
void main() {
    sequentialInsertTest();
    sequentialDeleteTest();
}// Of main

运行结果如下图:

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值