数据结构-线性表

线性表是数据结构中的一种基本形式,它由n个数据元素a1, a2, …, an组成,这些元素之间是有序的。

线性表中有两种基本逻辑结构:顺序存储结构和链式存储结构。在顺序存储结构中,线性表的元素按照其逻辑顺序依次存储在一块连续的存储空间中,而在链式存储结构中,线性表的元素通过指针相连,构成一个链式结构。

线性表具有以下几个特点:

  1. 有序性:线性表中的元素是有序排列的,每个元素都有其确定的位置和顺序。

  2. 单一性:除了第一个元素和最后一个元素之外,每个元素都有且仅有一个直接前驱元素和一个直接后继元素。

  3. 可变性:线性表的长度是可变的,可以动态地插入、删除元素,因此具有较大的灵活性。

  4. 存储结构多样:线性表可以采用不同的存储结构,如顺序存储结构(数组)和链式存储结构(链表),以适应不同的应用场景和需求。

  5. 常见应用:线性表是一种基础且常见的数据结构,广泛应用于各种算法和程序设计中,如数组、链表等都是线性表的具体应用。

  6. 基本操作:线性表具有一系列基本操作,如初始化、判空、清空、获取元素、定位元素、插入元素、删除元素、获取长度等,这些操作为对线性表的操作提供了标准接口,便于程序设计和算法实现。

线性表的抽象数据类型(ADT)定义如下:

ADT 线性表(List)
Data
    线性表的数据对象集合为{a1, a2, ..., an},每个元素的类型均为DataType。其中,除第一个元素a1外,每个元素有且只有一个直接前驱元素,除了最后一个元素an外,每个元素有且只有一个直接后继元素。数据元素之间的关系是一对一的关系。

Operation
    InitList(&L):初始化操作,建立一个空的线性表L。
    ListEmpty(L):若线性表为空,返回true;否则返回false。
    ClearList(&L):将线性表清空。
    GetElem(L, i, &e):将线性表L中第i个位置的元素值返回给e。
    LocateElem(L, e):在线性表L中查找与给定值e相等的元素,如果查找成功,返回该元素在表中的位置;否则返回0。
    ListInsert(&L, i, e):在线性表L中的第i个位置插入新元素e。
    ListDelete(&L, i, &e):删除线性表L中第i个位置的元素,并用e返回其值。
    ListLength(L):返回线性表L的元素个数。

通过这些操作可以对线性表进行初始化、判空、清空、获取元素、定位元素、插入元素、删除元素以及获取线性表长度等操作。

这些操作定义了线性表的基本功能和特性,可以作为线性表的标准接口,在具体实现时可以根据需要选择不同的存储结构来实现这些操作。

线性表作为一种基础的数据结构,被广泛应用于计算机科学领域,例如在数组、链表等数据结构中。

线性表的抽象数据类型定义提供了对线性表操作的标准化描述,为线性表的具体实现提供了清晰的接口,使得线性表可以被灵活地应用于不同的场景中。

#include 
#include 

#define MAX_SIZE 100

typedef struct {
    int data[MAX_SIZE];
    int length;
} SqList;

// 初始化操作,建立一个空的线性表L
void InitList(SqList *L) {
    L->length = 0;
}

// 若线性表为空,返回true;否则返回false
int ListEmpty(SqList L) {
    return L.length == 0 ? 1 : 0;
}

// 将线性表清空
void ClearList(SqList *L) {
    L->length = 0;
}

// 将线性表L中第i个位置的元素值返回给e
int GetElem(SqList L, int i, int *e) {
    if (i < 1 || i > L.length) {
        return 0;
    }
    *e = L.data[i - 1];
    return 1;
}

// 在线性表L中查找与给定值e相等的元素,如果查找成功,返回该元素在表中的位置;否则返回0
int LocateElem(SqList L, int e) {
    for (int i = 0; i < L.length; i++) {
        if (L.data[i] == e) {
            return i + 1;
        }
    }
    return 0;
}

// 在线性表L中的第i个位置插入新元素e
int ListInsert(SqList *L, int i, int e) {
    if (i < 1 || i > L->length + 1) {
        return 0;
    }
    if (L->length >= MAX_SIZE) {
        return 0;
    }
    for (int j = L->length; j >= i; j--) {
        L->data[j] = L->data[j - 1];
    }
    L->data[i - 1] = e;
    L->length++;
    return 1;
}

// 删除线性表L中第i个位置的元素,并用e返回其值
int ListDelete(SqList *L, int i, int *e) {
    if (i < 1 || i > L->length) {
        return 0;
    }
    *e = L->data[i - 1];
    for (int j = i; j < L->length; j++) {
        L->data[j - 1] = L->data[j];
    }
    L->length--;
    return 1;
}

// 返回线性表L的元素个数
int ListLength(SqList L) {
    return L.length;
}

int main() {
    SqList list;
    InitList(&list);
    ListInsert(&list, 1, 10);
    ListInsert(&list, 2, 20);
    ListInsert(&list, 3, 30);

    int e;
    if (GetElem(list, 2, &e)) {
        printf("The element at position 2 is: %d\n", e);
    } else {
        printf("Failed to get the element at position 2\n");
    }

    if (ListDelete(&list, 2, &e)) {
        printf("Deleted element: %d\n", e);
    } else {
        printf("Failed to delete element at position 2\n");
    }

    printf("Length of the list: %d\n", ListLength(list));

    return 0;
}

假设我们有一个任务跟踪应用程序,我们可以使用线性表来存储用户的任务列表。

#include 
#include 

#define MAX_TASKS 100

typedef struct {
    int task_id;
    char description[100];
} Task;

typedef struct {
    Task tasks[MAX_TASKS];
    int length;
} TaskList;

void InitTaskList(TaskList *list) {
    list->length = 0;
}

int AddTask(TaskList *list, int task_id, const char *description) {
    if (list->length >= MAX_TASKS) {
        return 0;  // 任务列表已满
    }
    Task new_task = {task_id, ""};
    int i = 0;
    while (description[i] != '\0' && i < 99) {
        new_task.description[i] = description[i];
        i++;
    }
    new_task.description[i] = '\0';
    list->tasks[list->length] = new_task;
    list->length++;
    return 1;  // 成功添加任务
}

int RemoveTask(TaskList *list, int task_id) {
    for (int i = 0; i < list->length; i++) {
        if (list->tasks[i].task_id == task_id) {
            for (int j = i; j < list->length - 1; j++) {
                list->tasks[j] = list->tasks[j + 1];
            }
            list->length--;
            return 1;  // 成功删除任务
        }
    }
    return 0;  // 未找到要删除的任务
}

void PrintTaskList(TaskList list) {
    printf("Current Tasks:\n");
    for (int i = 0; i < list.length; i++) {
        printf("Task ID: %d, Description: %s\n", list.tasks[i].task_id, list.tasks[i].description);
    }
}

int main() {
    TaskList tasks;
    InitTaskList(&tasks);

    AddTask(&tasks, 1, "Complete report");
    AddTask(&tasks, 2, "Meeting at 3pm");
    AddTask(&tasks, 3, "Prepare presentation");

    PrintTaskList(tasks);

    RemoveTask(&tasks, 2);

    PrintTaskList(tasks);

    return 0;
}

在这个例子中,我们使用了线性表来存储任务列表,每个任务有一个唯一的任务ID和描述。我们通过 AddTask 函数向任务列表中添加任务,通过 RemoveTask 函数删除任务,并通过 PrintTaskList 函数打印当前的任务列表。

你可能感兴趣的:(数据结构,算法,c语言)