C语言作为一种基础而强大的编程语言,在计算机科学和软件开发中占据着重要的地位。数据结构是C语言编程中不可或缺的一部分,它影响着程序的效率、可读性和可维护性。以下是对C语言中10种常见数据结构的详细解析及其应用场景。

1. 数组

数组是C语言中最基本的数据结构之一,用于存储具有相同数据类型的元素序列。数组可以通过索引直接访问元素,具有固定的长度。

应用场景

  • 存储大量数据,如成绩单、库存信息等。
  • 实现其他数据结构,如链表、栈、队列等。
#include <stdio.h>

int main() {
    int numbers[5] = {1, 2, 3, 4, 5};
    printf("The first element is %d\n", numbers[0]);
    return 0;
}

2. 链表

链表是一种非线性数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。

应用场景

  • 实现动态数据结构,如栈、队列、双向链表等。
  • 管理动态分配的内存。
#include <stdio.h>
#include <stdlib.h>

struct Node {
    int data;
    struct Node* next;
};

void insertAtHead(struct Node** head_ref, int new_data) {
    struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
    new_node->data = new_data;
    new_node->next = (*head_ref);
    (*head_ref) = new_node;
}

int main() {
    struct Node* head = NULL;
    insertAtHead(&head, 1);
    insertAtHead(&head, 2);
    insertAtHead(&head, 3);
    printf("Linked List: ");
    struct Node* temp = head;
    while (temp != NULL) {
        printf("%d ", temp->data);
        temp = temp->next;
    }
    return 0;
}

3. 栈

栈是一种后进先出(LIFO)的数据结构,元素只能从一端添加或移除。

应用场景

  • 函数调用栈。
  • 括号匹配验证。
#include <stdio.h>
#include <stdlib.h>

struct Stack {
    int top;
    unsigned capacity;
    int* array;
};

int isFull(struct Stack* stack) {
    return stack->top == stack->capacity - 1;
}

int isEmpty(struct Stack* stack) {
    return stack->top == -1;
}

void push(struct Stack* stack, int item) {
    if (isFull(stack))
        return;
    stack->array[++stack->top] = item;
}

int pop(struct Stack* stack) {
    if (isEmpty(stack))
        return -1;
    return stack->array[stack->top--];
}

int main() {
    struct Stack stack = { -1, 5, malloc(5 * sizeof(int)) };
    push(&stack, 10);
    push(&stack, 20);
    push(&stack, 30);
    printf("Popped element is %d\n", pop(&stack));
    return 0;
}

4. 队列

队列是一种先进先出(FIFO)的数据结构,元素只能从一端添加,从另一端移除。

应用场景

  • 任务调度。
  • 缓冲区管理。
#include <stdio.h>
#include <stdlib.h>

struct Queue {
    int front, rear, size;
    unsigned capacity;
    int* array;
};

int isFull(struct Queue* queue) {
    return queue->size == queue->capacity;
}

int isEmpty(struct Queue* queue) {
    return queue->size == 0;
}

void enqueue(struct Queue* queue, int item) {
    if (isFull(queue))
        return;
    queue->array[queue->rear++] = item;
    queue->size++;
}

int dequeue(struct Queue* queue) {
    if (isEmpty(queue))
        return -1;
    int item = queue->array[queue->front++];
    queue->size--;
    return item;
}

int main() {
    struct Queue queue = { 0, 0, 5, 5, malloc(5 * sizeof(int)) };
    enqueue(&queue, 10);
    enqueue(&queue, 20);
    enqueue(&queue, 30);
    printf("Dequeued element is %d\n", dequeue(&queue));
    return 0;
}

5. 树

树是一种非线性数据结构,由节点组成,每个节点包含数据和一个或多个子节点。

应用场景

  • 文件系统。
  • 组织结构。
#include <stdio.h>
#include <stdlib.h>

struct Node {
    int data;
    struct Node* left;
    struct Node* right;
};

struct Node* newNode(int data) {
    struct Node* node = (struct Node*)malloc(sizeof(struct Node));
    node->data = data;
    node->left = node->right = NULL;
    return node;
}

struct Node* insert(struct Node* node, int data) {
    if (node == NULL) return newNode(data);
    if (data < node->data)
        node->left = insert(node->left, data);
    else if (data > node->data)
        node->right = insert(node->right, data);
    return node;
}

int main() {
    struct Node* root = NULL;
    root = insert(root, 50);
    insert(root, 30);
    insert(root, 20);
    insert(root, 40);
    insert(root, 70);
    insert(root, 60);
    insert(root, 80);
    return 0;
}

6. 图

图是一种复杂的数据结构,由节点和边组成,节点可以表示实体,边表示实体之间的关系。

应用场景

  • 社交网络。
  • 路径规划。
#include <stdio.h>
#include <stdlib.h>

struct Graph {
    int numVertices;
    int** adjMatrix;
};

struct Graph* createGraph(int vertices) {
    struct Graph* graph = (struct Graph*)malloc(sizeof(struct Graph));
    graph->numVertices = vertices;
    graph->adjMatrix = (int**)malloc(vertices * sizeof(int*));
    for (int i = 0; i < vertices; i++)
        graph->adjMatrix[i] = (int*)malloc(vertices * sizeof(int));
    for (int i = 0; i < vertices; i++)
        for (int j = 0; j < vertices; j++)
            graph->adjMatrix[i][j] = 0;
    return graph;
}

void addEdge(struct Graph* graph, int src, int dest) {
    graph->adjMatrix[src][dest] = 1;
    graph->adjMatrix[dest][src] = 1;
}

int main() {
    struct Graph* graph = createGraph(4);
    addEdge(graph, 0, 1);
    addEdge(graph, 0, 2);
    addEdge(graph, 1, 2);
    addEdge(graph, 2, 3);
    return 0;
}

7. 散列表

散列表是一种基于散列函数的数据结构,用于存储键值对。

应用场景

  • 字典。
  • 缓存。
#include <stdio.h>
#include <stdlib.h>

#define TABLE_SIZE 10

struct HashNode {
    int key;
    int value;
    struct HashNode* next;
};

struct HashTable {
    struct HashNode* hashTable[TABLE_SIZE];
};

int hashFunction(int key) {
    return key % TABLE_SIZE;
}

struct HashTable* createHashTable() {
    struct HashTable* table = (struct HashTable*)malloc(sizeof(struct HashTable));
    for (int i = 0; i < TABLE_SIZE; i++)
        table->hashTable[i] = NULL;
    return table;
}

void insert(struct HashTable* table, int key, int value) {
    int index = hashFunction(key);
    struct HashNode* newNode = (struct HashNode*)malloc(sizeof(struct HashNode));
    newNode->key = key;
    newNode->value = value;
    newNode->next = table->hashTable[index];
    table->hashTable[index] = newNode;
}

int main() {
    struct HashTable* table = createHashTable();
    insert(table, 10, 100);
    insert(table, 20, 200);
    insert(table, 30, 300);
    printf("Value of key 20 is %d\n", table->hashTable[hashFunction(20)]->value);
    return 0;
}

8. 跳表

跳表是一种基于链表的数据结构,通过增加多级索引来提高查找效率。

应用场景

  • 实现有序集合。
  • 缓存。
#include <stdio.h>
#include <stdlib.h>

#define MAX_LEVEL 5

struct Node {
    int key;
    struct Node* forward[MAX_LEVEL];
};

struct Node* createNode(int key) {
    struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
    newNode->key = key;
    for (int i = 0; i < MAX_LEVEL; i++)
        newNode->forward[i] = NULL;
    return newNode;
}

void insert(struct Node** head, int key) {
    struct Node* node = createNode(key);
    struct Node* temp = *head;
    int level = 0;
    while (temp != NULL && level < MAX_LEVEL) {
        node->forward[level] = temp->forward[level];
        temp->forward[level] = node;
        temp = temp->forward[0];
        level++;
    }
    *head = node;
}

int main() {
    struct Node* head = NULL;
    insert(&head, 1);
    insert(&head, 3);
    insert(&head, 5);
    insert(&head, 7);
    insert(&head, 9);
    return 0;
}

9. 堆

堆是一种基于完全二叉树的数据结构,常用于实现优先队列。

应用场景

  • 优先队列。
  • 排序。
#include <stdio.h>
#include <stdlib.h>

void swap(int* a, int* b) {
    int t = *a;
    *a = *b;
    *b = t;
}

void heapify(int arr[], int n, int i) {
    int largest = i;
    int left = 2 * i + 1;
    int right = 2 * i + 2;
    if (left < n && arr[left] > arr[largest])
        largest = left;
    if (right < n && arr[right] > arr[largest])
        largest = right;
    if (largest != i) {
        swap(&arr[i], &arr[largest]);
        heapify(arr, n, largest);
    }
}

void heapSort(int arr[], int n) {
    for (int i = n / 2 - 1; i >= 0; i--)
        heapify(arr, n, i);
    for (int i = n - 1; i >= 0; i--) {
        swap(&arr[0], &arr[i]);
        heapify(arr, i, 0);
    }
}

int main() {
    int arr[] = {12, 11, 13, 5, 6, 7};
    int n = sizeof(arr) / sizeof(arr[0]);
    heapSort(arr, n);
    printf("Sorted array is \n");
    for (int i = 0; i < n; ++i)
        printf("%d ", arr[i]);
    printf("\n");
    return 0;
}

10. 并查集

并查集是一种用于处理一些不交集的合并及查询问题的数据结构。

应用场景

  • 路径压缩。
  • 查询压缩。
#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 100

int parent[MAX_SIZE];

int find(int x) {
    if (parent[x] != x)
        parent[x] = find(parent[x]);
    return parent[x];
}

void unionSets(int x, int y) {
    int rootX = find(x);
    int rootY = find(y);
    if (rootX != rootY)
        parent[rootX] = rootY;
}

int main() {
    int n = 5;
    parent[0] = 0;
    parent[1] = 1;
    parent[2] = 2;
    parent[3] = 3;
    parent[4] = 4;
    unionSets(1, 2);
    unionSets(2, 3);
    unionSets(4, 5);
    printf("Root of 3 is %d\n", find(3));
    printf("Root of 4 is %d\n", find(4));
    return 0;
}

通过以上对C语言中10种常见数据结构的详解与应用,相信您已经对这些数据结构有了更深入的了解。在实际编程过程中,合理选择和使用数据结构能够使程序更加高效、易读和易维护。希望这些内容对您的学习和实践有所帮助。