1.线性表

167 阅读3分钟

一.线性表的概述与理解

        线性表是比较简单的一种数据结构,在上个学期学生管理系统的构建过程中,有做过一些初步的了解。线性表分为两种,一个是顺序储存的线性表,另外一个是链式储存的。

        顺序储存的最大特点是在内存中的排列是连续的,数组也可以看成是顺序储存的线性表。链式储存的话,典型代表是链表,元素在内存中的排列是不连续的,准确地说在堆里面是不连续的。

二."临摹"与理解闵帆老师的顺序表代码

2.1 结构体

typedef struct SequentialList
{
    int actualLength;

    int data[LIST_MAX_LENGTH]; // The maximum length is fixed.
} * SequentialListPtr;

结构体内定义了线性表的长度,以及一个连续的数组;

2.2 打印顺序表

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

遍历元素进行打印

2.3 打印顺序表地址

void outputMemory(SequentialListPtr paraListPtr)
{
    printf("The address of the structure: %ld\r\n", paraListPtr);
    printf("The address of actualLength: %ld\r\n", &paraListPtr->actualLength);
    printf("The address of data: %ld\r\n", &paraListPtr->data);
    printf("The address of actual data: %ld\r\n", &paraListPtr->data[0]);
    printf("The address of second data: %ld\r\n", &paraListPtr->data[1]);
}

2.4 创建线性表

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];
    } // Of for i
    resultPtr->actualLength = paraLength;

    return resultPtr;
} // Of sequentialListInit

malloc申请堆内存空间;将paraData数组中的内容转置于顺序表之中

2.5 线性表的插入

void sequentialListInsert(SequentialListPtr paraListPtr, int paraPosition, int paraValue)
{
    // Step 1. Space check.
    if (paraListPtr->actualLength >= LIST_MAX_LENGTH)
    {
        printf("Cannot insert element: list full.\r\n");
        return;
    } // Of if

    // Step 2. Position check.
    if (paraPosition < 0)
    {
        printf("Cannot insert element: negative position unsupported.");
        return;
    } // Of if
    if (paraPosition > paraListPtr->actualLength)
    {
        printf("Cannot insert element: the position %d is bigger than the list length %d.\r\n", paraPosition, paraListPtr->actualLength);
        return;
    } // Of if

    // Step 3. Move the remaining part.
    for (int i = paraListPtr->actualLength; i > paraPosition; i--)
    {
        paraListPtr->data[i] = paraListPtr->data[i - 1];
    } // Of for i

    // Step 4. Insert.
    paraListPtr->data[paraPosition] = paraValue;

    // Step 5. Update the length.
    paraListPtr->actualLength++;
} // Of sequentialListInsert

首先对功能的合理性进行判断,一个是用来判断是否超过顺序表的最大限度,一个用来判断插入的位置是否合法。之后将元素插入,并且后移其后内容。

2.6 线性表插入的结果验证

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

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

    // Initialize.
    SequentialListPtr tempList = sequentialListInit(tempArray, 5);
    printf("After initialization, the list is: ");
    outputList(tempList);

    // Insert to the first.
    printf("Now insert to the first, the list is: ");
    sequentialListInsert(tempList, 0, 8);
    outputList(tempList);

    // Insert to the last.
    printf("Now insert to the last, the list is: ");
    sequentialListInsert(tempList, 6, 9);
    outputList(tempList);

    // Insert beyond the tail.
    printf("Now insert beyond the tail. \r\n");
    sequentialListInsert(tempList, 8, 9);
    printf("The list is:");
    outputList(tempList);

    // Insert to position 3.
    for (i = 0; i < 5; i++)
    {
        printf("Inserting %d.\r\n", (i + 10));
        sequentialListInsert(tempList, 0, (i + 10));
        outputList(tempList);
    } // Of for i

    printf("---- sequentialInsertTest ends. ----\r\n");
} // Of sequentialInsertTest

通过打印的方式来进行验证。

2.7 线性表的删除

int sequentialListDelete(SequentialListPtr paraListPtr, int paraPosition)
{
    // Step 1. Position check.
    if (paraPosition < 0)
    {
        printf("Invalid position: %d.\r\n", paraPosition);
        return -1;
    } // Of if

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

    // Step 2. Move the remaining part.
    int resultValue = paraListPtr->data[paraPosition];
    for (int i = paraPosition; i < paraListPtr->actualLength; i++)
    {
        paraListPtr->data[i] = paraListPtr->data[i + 1];
    } // Of for i

    // Step 3. Update the length.
    paraListPtr->actualLength--;

    // Step 4. Return the value.
    return resultValue;
} // Of sequentialListDelete

首先检查调用函数输入参数的合理性,之后将指定元素删除,并且将元素前移。结构体内Length--

2.8 线性表的删除结果测试

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

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

    // Initialize.
    SequentialListPtr tempList = sequentialListInit(tempArray, 5);
    printf("After initialization, the list is: ");
    outputList(tempList);

    // Delete the first.
    printf("Now delete the first, the list is: ");
    sequentialListDelete(tempList, 0);
    outputList(tempList);

    // Delete to the last.
    printf("Now delete the last, the list is: ");
    sequentialListDelete(tempList, 3);
    outputList(tempList);

    // Delete the second.
    printf("Now delete the second, the list is: ");
    sequentialListDelete(tempList, 1);
    outputList(tempList);

    // Delete the second.
    printf("Now delete the 5th, the list is: ");
    sequentialListDelete(tempList, 5);
    outputList(tempList);

    // Delete the second.
    printf("Now delete the (-6)th, the list is: ");
    sequentialListDelete(tempList, -6);
    outputList(tempList);

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

    outputMemory(tempList);
} // Of sequentialDeleteTest

2.9 线性表元素的local

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

2.10 线性表元素的GET

int getElement(SequentialListPtr paraListPtr, int paraPosition)
{
    // Step 1. Position check.
    if (paraPosition < 0)
    {
        printf("Invalid position: %d.\r\n", paraPosition);
        return -1;
    } // Of if

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

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

通过输入位置,将指定位置的元素返回。

2.11 线性表元素的Clear

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

将长度归0,使得一些函数的合理性判断return FALSE。