【数据结构和算法 第二章】线性表(逻辑结构)

请添加图片描述

0 引言

今天继续数据结构和算法的学习,开启第二章内容的学习线性表。

1 线性表(逻辑结构)

线性表是一种基本的数据结构,其特点是数据元素之间是一对一的线性关系。在线性表中,每个数据元素(除了第一个和最后一个之外)都有一个前驱和一个后继,即每个元素都只有一个直接前驱和一个直接后继。这种结构可以形象地类比为一列排队的人,每个人(除了队首和队尾的人)都有一个前面的人和一个后面的人。

1.1 特点

  1. 有序性:线性表中的元素具有自然的顺序性,即元素之间是按一定的顺序排列的。
  2. 一对一的关系:线性表中的每个数据元素(除了第一个和最后一个元素)都有且仅有一个直接前驱和一个直接后继。

1.2 应用

线性表是数据结构中最简单和最常用的一种结构,广泛应用于实现各种更高级的数据结构和算法,如栈、队列、字符串处理等。在实际编程中,根据具体需求选择适当的线性表结构,可以显著影响程序的性能和效率。

2 线性表的物理结构

2.1 顺序存储线性表

用 C 语言来实现一个线性表的顺序存储结构。这里我们创建一个简单的顺序表结构,并提供添加、删除和获取元素的功能。

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

#define MAX_SIZE 10

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

void initList(SequentialList *list) {
    list->length = 0;
}

int insert(SequentialList *list, int index, int value) {
    if (list->length == MAX_SIZE) {
        printf("List is full\n");
        return -1;
    }
    if (index < 0 || index > list->length) {
        printf("Index out of bounds\n");
        return -1;
    }

    for (int i = list->length - 1; i >= index; i--) {
        list->data[i + 1] = list->data[i];
    }
    list->data[index] = value;
    list->length++;
    return 0;
}

int delete(SequentialList *list, int index) {
    if (list->length == 0) {
        printf("List is empty\n");
        return -1;
    }
    if (index < 0 || index >= list->length) {
        printf("Index out of bounds\n");
        return -1;
    }

    for (int i = index; i < list->length - 1; i++) {
        list->data[i] = list->data[i + 1];
    }
    list->length--;
    return 0;
}

int get(SequentialList *list, int index) {
    if (index < 0 || index >= list->length) {
        printf("Index out of bounds\n");
        return -1;
    }
    return list->data[index];
}

void printList(SequentialList *list) {
    for (int i = 0; i < list->length; i++) {
        printf("%d ", list->data[i]);
    }
    printf("\n");
}

int main() {
    SequentialList list;
    initList(&list);

    insert(&list, 0, 10);
    insert(&list, 1, 20);
    insert(&list, 1, 30);
    printList(&list); // 输出: 10 30 20

    delete(&list, 1);
    printList(&list); // 输出: 10 20

    printf("Element at index 1: %d\n", get(&list, 1)); // 输出: Element at index 1: 20

    return 0;
}

在这个例子中:

  • SequentialList 结构体用于存储线性表的数据和长度。
  • initList 函数用于初始化线性表。
  • insert 函数用于在指定位置插入一个元素。
  • delete 函数用于删除指定位置的元素。
  • get 函数用于获取指定位置的元素。
  • printList 函数用于打印线性表的所有元素。

这段代码展示了顺序存储线性表在 C 语言中的基本实现,包括了一些基础的错误检查。需要注意的是,这个实现的数组大小是固定的,实际应用中可能需要动态调整数组的大小以适应不同的需求。

2.2 链式存储线性表

我明白您的担忧,代码格式的确很重要,特别是在C语言这样的语言中,清晰的代码格式可以大大增强代码的可读性和维护性。下面是重新格式化的代码,我将确保它更加整洁和规范:

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

// 定义链表节点结构体
typedef struct Node {
    int data;
    struct Node *next;
} Node;

// 创建新节点
Node* createNode(int data) {
    Node *newNode = (Node *)malloc(sizeof(Node));
    if (!newNode) {
        printf("Memory allocation failed\n");
        exit(1);
    }
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}

// 在链表的指定位置插入新节点
void insertNode(Node **head, int data, int position) {
    Node *newNode = createNode(data);
    if (position == 0) {
        newNode->next = *head;
        *head = newNode;
    } else {
        Node *current = *head;
        for (int i = 0; current != NULL && i < position - 1; i++) {
            current = current->next;
        }
        if (current == NULL) {
            printf("Position out of bounds\n");
        } else {
            newNode->next = current->next;
            current->next = newNode;
        }
    }
}

// 删除链表中指定位置的节点
void deleteNode(Node **head, int position) {
    if (*head == NULL) {
        printf("List is empty\n");
        return;
    }
    Node *temp = *head;
    if (position == 0) {
        *head = temp->next;
        free(temp);
    } else {
        for (int i = 0; temp != NULL && i < position - 1; i++) {
            temp = temp->next;
        }
        if (temp == NULL || temp->next == NULL) {
            printf("Position out of bounds\n");
            return;
        }
        Node *next = temp->next->next;
        free(temp->next);
        temp->next = next;
    }
}

// 打印链表
void printList(Node *head) {
    while (head != NULL) {
        printf("%d -> ", head->data);
        head = head->next;
    }
    printf("NULL\n");
}

// 主函数
int main() {
    Node *head = NULL;

    insertNode(&head, 10, 0); // List: 10
    insertNode(&head, 20, 1); // List: 10 -> 20
    insertNode(&head, 30, 2); // List: 10 -> 20 -> 30
    printList(head);

    deleteNode(&head, 1); // Delete element at position 1: 10 -> 30
    printList(head);

    // 清理内存
    while (head != NULL) {
        Node *temp = head;
        head = head->next;
        free(temp);
    }

    return 0;
}
  • 11
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值