在编程语言中,数据结构是组织、管理和存储数据的方式。C语言作为一种结构化编程语言,提供了丰富的数据结构,其中顺序表(也称为数组)是最基本的数据结构之一。顺序表在内存中是连续存储的,这使得它在访问和处理数据时非常高效。在本文中,我们将深入探讨C语言中顺序表的概念、特点以及基本操作。
一、什么是顺序表?
顺序表是一种线性表的数据结构,其元素在内存中是连续存储的。这意味着每个元素都有一个固定的内存地址,可以通过基地址和偏移量来访问。顺序表的这种特性使得它在数据访问上非常快速,尤其是对于索引访问。
二、顺序表的特点
- 连续存储:顺序表的元素在内存中是连续存储的,这使得顺序表的访问速度非常快。
- 固定大小:在C语言中,一旦定义了顺序表的大小,它就不能再改变。这与动态数组(如链表)不同,后者可以根据需要动态地增加或减少大小。
- 随机访问:由于元素在内存中是连续存储的,顺序表支持随机访问,即可以直接通过索引访问任何元素。
三、顺序表的基本操作
1. 定义顺序表
在C语言中,定义顺序表通常使用数组。例如,定义一个整型顺序表:
int array[10]; // 定义一个包含10个整数的顺序表
2. 初始化顺序表
顺序表可以在定义时初始化,也可以在定义后初始化:
int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // 定义并初始化
int array2[10];
for (int i = 0; i < 10; i++) {
array2[i] = i + 1; // 定义后初始化
}
3. 访问顺序表元素
访问顺序表的元素非常简单,只需要使用索引即可:
int value = array[3]; // 访问第4个元素,值为4
4. 修改顺序表元素
修改顺序表的元素同样简单,只需将新值赋给相应的索引即可:
array[3] = 100; // 将第4个元素的值修改为100
5. 遍历顺序表
遍历顺序表是处理顺序表数据的基本操作之一:
for (int i = 0; i < 10; i++) {
printf("%d ", array[i]);
}
6. 插入和删除元素
虽然顺序表的大小是固定的,但我们可以通过移动元素来模拟插入和删除操作:
// 插入元素
for (int i = 9; i >= 3; i--) {
array[i + 1] = array[i]; // 从第4个元素开始向后移动
}
array[3] = 99; // 在第4个位置插入99
// 删除元素
for (int i = 3; i < 10; i++) {
array[i] = array[i + 1]; // 从第4个元素开始向前移动
}
四、顺序表的基本操作实训
1、顺序表的建立。从键盘输入n个整数,并将这些整数存入顺序表中,修改表长后建立表L。
#include <stdio.h>
#include <stdlib.h>
// 定义顺序表的结构体
typedef struct {
int *data; // 指向数组的指针,用于存储整数
int length; // 顺序表的当前长度
int capacity; // 顺序表的最大容量
} SeqList;
// 初始化顺序表
void initSeqList(SeqList *list, int capacity) {
list->data = (int *)malloc(capacity * sizeof(int));
if (list->data == NULL) {
printf("Memory allocation failed.\n");
exit(1);
}
list->length = 0;
list->capacity = capacity;
}
// 销毁顺序表
void destroySeqList(SeqList *list) {
free(list->data);
list->data = NULL;
list->length = 0;
list->capacity = 0;
}
// 向顺序表中添加元素
void addElement(SeqList *list, int element) {
if (list->length == list->capacity) {
int newCapacity = list->capacity * 2;
int *newData = (int *)realloc(list->data, newCapacity * sizeof(int));
if (newData == NULL) {
printf("内存重新分配失败");
exit(1);
}
list->data = newData;
list->capacity = newCapacity;
}
list->data[list->length++] = element;
}
// 打印顺序表中的元素
void printSeqList(SeqList *list) {
for (int i = 0; i < list->length; i++) {
printf("%d ", list->data[i]);
}
printf("\n");
}
int main() {
SeqList list;
int n, input;
printf("你要输入的整数是: ");
scanf("%d", &n);
// 初始化顺序表,假设初始容量为10
initSeqList(&list, 10);
printf("请输入 %d 个整数: ", n);
for (int i = 0; i < n; i++) {
scanf("%d", &input);
addElement(&list, input);
}
printf("序列列表中的元素是: ");
printSeqList(&list);
// 销毁顺序表,释放内存
destroySeqList(&list);
return 0;
}
2、线性表的插入运算是指在线性表的第i个(1≤i≤n+1)位置上,插入一个新元素x,使长度为n的线性表(a1,a2, …, ai,…,an)变成长度为n+1的线性表(a1,a2, …, ai-1, x, ai,…,an)。
#include <stdio.h>
#include <stdlib.h>
void insertElement(int **arr, int *size, int position, int x);
void printArray(int *arr, int size);
int main() {
int *array = (int *)malloc(5 * sizeof(int));
if (array == NULL) {
printf("Memory allocation failed.\n");
return 1;
}
for (int i = 0; i < 5; i++) {
array[i] = i + 1;
}
int size = 5;
int position, x;
printf("请输入要插入的位置 (1到%d):", size + 1);
scanf("%d", &position);
printf("请输入要插入的元素:");
scanf("%d", &x);
if (position < 1 || position > size + 1) {
printf("位置无效。\n");
} else {
insertElement(&array, &size, position, x);
printf("更新后的数组:\n");
printArray(array, size);
free(array);
}
return 0;
}
void insertElement(int **arr, int *size, int position, int x) {
*arr = (int *)realloc(*arr, (*size + 1) * sizeof(int));
if (*arr == NULL) {
printf("内存分配失败。\n");
exit(1);
}
for (int i = *size - 1; i >= position - 1; i--) {
(*arr)[i + 1] = (*arr)[i];
}
(*arr)[position - 1] = x;
(*size) = (*size) + 1;
}
void printArray(int *arr, int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}