初步认识线性表

本文详细介绍了线性表的数据结构定义,包括记录和文件的概念,并展示了如何在C语言中实现线性表的基本操作,如创建、打印、插入和删除元素。通过示例代码解释了插入和删除的逻辑,以及对错误情况的处理。同时,提供了查找元素位置和获取指定位置元素值的函数。文章最后进行了插入和删除操作的测试,确保了功能的正确性。
摘要由CSDN通过智能技术生成

1 线性表的定义

线性表 (linear list) 是 数据结构 的一种,一个线性表是n个具有相同特性的数据元素的有限序列。

在稍复杂的线性表中,一个数据元素可由多个数据项(item)组成,此种情况下常把数据元素称为记录(record),含有大量记录的线性表又称文件(file)

线性表中的个数n定义为线性表的长度,n=0时称为空表。在非空表中每个数据元素都有一个确定的位置,如用ai表示数据元素,则i称为数据元素ai在线性表中的位序。

线性表的相邻元素之间存在着序偶关系。如用(a1,…,ai-1,ai,ai+1,…,an)表示一个顺序表,则表中ai-1领先于ai,ai领先于ai+1,称ai-1是ai的直接前驱元素,ai+1是ai的直接后继元素。当i=1,2,…,n-1时,ai有且仅有一个直接后继,当i=2,3,…,n时,ai有且仅有一个直接前驱

2 操作线性表 

1)第一步当然是创建一个链表

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

#define LIST_MAX_LENGTH 10


typedef struct SequentialList {
    int actualLength;

    int data[LIST_MAX_LENGTH]; 
} *SequentialListPtr;

//(别忘了头函数!)

2)然后就是把它打印出来 

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("看一下各项数据的地址:\r\n");
    printf("结构的地址: %ld\r\n", paraListPtr);
    printf("存储大小的地址是: %ld\r\n", &paraListPtr->actualLength);
    printf("data的地址是: %ld\r\n", &paraListPtr->data);
    printf("data的首地址是: %ld\r\n", &paraListPtr->data[0]);
    printf("data的第二位地址是: %ld\r\n", &paraListPtr->data[1]);
}

3)开始初始化链表 

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;
}

4)在这个链表里插入一个元素

void sequentialListInsert(SequentialListPtr paraListPtr, int paraPosition, int paraValue) {
    // 第一步,检查空间是否足够
    if (paraListPtr->actualLength >= LIST_MAX_LENGTH) {
        printf("Cannot insert element: list full.\r\n");
        return;
    }//大了就装不下了

    // 第二步,检查一下位置是否正确
    if (paraPosition < 0) {
        printf("Cannot insert element: negative position unsupported.");
        return;
    }
    if (paraPosition > paraListPtr->actualLength) {
        printf("Cannot insert element: the position %d is bigger than the list length %d.\r\n", paraPosition, paraListPtr->actualLength);
        return;
    }//位置不对插不进去

    // 第三步,移动主要数据
    for (int i = paraListPtr->actualLength; i > paraPosition; i --) {
        paraListPtr->data[i] = paraListPtr->data[i - 1];
    }//整体后移一位,腾个位置出来

    // 第四步,开插!
    paraListPtr->data[paraPosition] = paraValue;

    // 第五步,更新一下长度
    paraListPtr->actualLength ++;
}

5)插入测试一下看有没有问题

//随机测试
void sequentialInsertTest() {
    int i;
    int tempArray[5] = {3, 5, 2, 7, 4};

    printf("---- sequentialInsertTest begins. ----\r\n");

    // 初始化链表
    SequentialListPtr tempList = sequentialListInit(tempArray, 5);
    printf("After initialization, the list is: ");
    outputList(tempList);

    // 在0位置插入8
    printf("Now insert to the first, the list is: ");
    sequentialListInsert(tempList, 0, 8);
    outputList(tempList);

    // 在6位置插入9
    printf("Now insert to the last, the list is: ");
    sequentialListInsert(tempList, 6, 9);
    outputList(tempList);

    // 插几个不合法的数
    printf("Now insert beyond the tail. \r\n");
    sequentialListInsert(tempList, 77, 999);
    sequentialListInsert(tempList, -9, 999);
    printf("The list is:");
    outputList(tempList);

    // 首插演示
    for (i = 0; i < 5; i ++) {
        printf("Inserting %d.\r\n", (i + 10));
        sequentialListInsert(tempList, 0, (i + 10));
        outputList(tempList);
    }

    printf("---- 顺序插入测试结束 ----\r\n");
}

6)现在是删除元素的操作

int sequentialListDelete(SequentialListPtr paraListPtr, int paraPosition) {
    // 第一步,检查位置是否合理
    if (paraPosition < 0) {
        printf("Invalid position: %d.\r\n", paraPosition);
        return -1;
    }

    if (paraPosition >= paraListPtr->actualLength) {
        printf("Cannot delete element: the position %d is beyond the list length %d.\r\n", paraPosition, paraListPtr->actualLength);
        return -1;
    }//不合理返回-1

    // 第二步,移动这些数据
    int resultValue = paraListPtr->data[paraPosition];
    for (int i = paraPosition; i < paraListPtr->actualLength; i ++) {
        paraListPtr->data[i] = paraListPtr->data[i + 1];
    }//腾位置
    // 第三步,更新长度
    paraListPtr->actualLength --;

    // 最后,返回值
    return resultValue;
}

7)测试一下删除功能有没有问题 

void sequentialDeleteTest() {
    int tempArray[5] = {3, 5, 2, 7, 4};

    printf("---- sequentialDeleteTest begins. ----\r\n");

    // 初始化链表
    SequentialListPtr tempList = sequentialListInit(tempArray, 5);
    printf("After initialization, the list is: ");
    outputList(tempList);

    // 删除首位
    printf("Now delete the first, the list is: ");
    sequentialListDelete(tempList, 0);
    outputList(tempList);

    // 再删除末位
    printf("Now delete the last, the list is: ");
    sequentialListDelete(tempList, 3);
    outputList(tempList);

    // 然后一直删除第二位
    printf("Now delete the second, the list is: ");
    sequentialListDelete(tempList, 1);
    outputList(tempList);

    printf("Now delete the 5th, the list is: ");
    sequentialListDelete(tempList, 5);
    outputList(tempList);
    
    //选一个不合法的位置删掉,和插入操作一样
    printf("Now delete the (-6)th, the list is: ");
    sequentialListDelete(tempList, -6);
    outputList(tempList);

    printf("---- 顺序删除测试结束 ----\r\n");

    OutputMemory(tempList);
}

 8)做一个返回指定元素位置的函数

int locateElement(SequentialListPtr paraListPtr, int paraValue) {
    if (paraValue < 0 ||paraValue >paraListPtr->actualLength) {
            printf("Wrong input! Please re-enter it!");
                return -1;
        }//不合法直接pass
    for (int i = 0; i < paraListPtr->actualLength; i ++) {
          if (paraListPtr->data[i] == paraValue) 
        {
            return i;
        }//对了直接返回i
    }
}

9)再搞一个返回第n个位置的值的函数 

int getElement(SequentialListPtr paraListPtr, int paraPosition) {
    // 检查输入是否合法
    if (paraPosition < 0 || paraPosition >= paraListPtr->actualLength) {
        printf("Invalid position: %d.\r\n", paraPosition);
        return -1;}
    // 合法就返回值
    return paraListPtr->data[paraPosition-1];
}

10)最后清空顺序表

void clearList(SequentialListPtr paraListPtr) {
    paraListPtr->actualLength = 0;
}

函数的实现

void main() {
    sequentialInsertTest();
    sequentialDeleteTest();
}

运行结果 

 

不才学艺不精,如有问题欢迎指正。
最后,再次感谢各位的阅读。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值