实现线性表的链式存储定义,完成单链表的创建(头插法、尾插法)、插入、删除、查找等常用操作,将线性链表逆置,即最后一个结点变成第一个结点,原来倒数第二个结点变成第二个结点,以此类推。
时间: 2023-10-19 13:24:20 浏览: 46
线性表的链式存储定义可以通过结构体和指针实现,如下所示:
```c
typedef struct Node {
int data; // 数据域
struct Node* next; // 指针域,指向下一个节点
} Node, *LinkedList; // 定义Node为结构体类型,LinkedList为指向Node的指针类型
```
接下来我们可以实现单链表的创建、插入、删除和查找等常用操作。
### 头插法创建单链表
头插法是指将新节点插入到链表的头部,即新节点成为链表的第一个节点。以下是头插法创建单链表的代码实现:
```c
LinkedList createListByHeadInsert(int* arr, int n) {
LinkedList head = (LinkedList)malloc(sizeof(Node)); // 创建头节点
head->next = NULL; // 初始时链表为空
for (int i = 0; i < n; i++) {
Node* newNode = (Node*)malloc(sizeof(Node)); // 创建新节点
newNode->data = arr[i]; // 赋值
newNode->next = head->next; // 插入到头节点后面
head->next = newNode;
}
return head;
}
```
### 尾插法创建单链表
尾插法是指将新节点插入到链表的尾部,即新节点成为链表的最后一个节点。以下是尾插法创建单链表的代码实现:
```c
LinkedList createListByTailInsert(int* arr, int n) {
LinkedList head = (LinkedList)malloc(sizeof(Node)); // 创建头节点
head->next = NULL; // 初始时链表为空
LinkedList tail = head; // tail指向链表的最后一个节点
for (int i = 0; i < n; i++) {
Node* newNode = (Node*)malloc(sizeof(Node)); // 创建新节点
newNode->data = arr[i]; // 赋值
newNode->next = NULL; // 新节点插入到尾部,所以指针域为NULL
tail->next = newNode; // 插入到链表尾部
tail = newNode; // 更新tail指针
}
return head;
}
```
### 插入节点
插入节点操作是将新节点插入到链表的任意位置。以下是插入节点的代码实现:
```c
void insertNode(LinkedList list, int index, int data) {
int i = 0;
Node* p = list;
while (p != NULL && i < index - 1) { // 找到要插入的位置
p = p->next;
i++;
}
if (p == NULL || i > index - 1) { // 如果超出链表长度,则直接返回
return;
}
Node* newNode = (Node*)malloc(sizeof(Node)); // 创建新节点
newNode->data = data; // 赋值
newNode->next = p->next; // 插入到p节点后面
p->next = newNode;
}
```
### 删除节点
删除节点操作是将链表中的某个节点删除。以下是删除节点的代码实现:
```c
void deleteNode(LinkedList list, int index) {
int i = 0;
Node* p = list;
while (p != NULL && i < index - 1) { // 找到要删除的位置
p = p->next;
i++;
}
if (p == NULL || p->next == NULL || i > index - 1) { // 如果超出链表长度,则直接返回
return;
}
Node* q = p->next; // q指向要删除的节点
p->next = q->next; // 将q节点从链表中删除
free(q); // 释放q节点的内存
}
```
### 查找节点
查找节点操作是根据节点的值或者下标查找链表中的某个节点。以下是查找节点的代码实现:
```c
Node* findNodeByValue(LinkedList list, int data) {
Node* p = list->next; // p指向第一个节点
while (p != NULL && p->data != data) { // 查找值为data的节点
p = p->next;
}
return p;
}
Node* findNodeByIndex(LinkedList list, int index) {
int i = 0;
Node* p = list->next; // p指向第一个节点
while (p != NULL && i < index) { // 查找下标为index的节点
p = p->next;
i++;
}
return p;
}
```
### 逆置链表
将链表逆置是指将链表中的所有节点按照相反的顺序重新排列。以下是逆置链表的代码实现:
```c
LinkedList reverseList(LinkedList list) {
if (list == NULL || list->next == NULL) { // 如果链表为空或者只有一个节点,则直接返回
return list;
}
Node* p = list->next; // p指向第一个节点
Node* q = p->next; // q指向p的下一个节点
p->next = NULL; // 将第一个节点的指针域设为NULL
while (q != NULL) { // 逐个逆置节点
Node* r = q->next; // r指向q的下一个节点
q->next = p; // 将q的指针域指向p
p = q; // 更新p指针
q = r; // 更新q指针
}
list->next = p; // 将头节点指向p节点
return list;
}
```
以上就是线性表的链式存储定义以及单链表的创建、插入、删除、查找等常用操作的代码实现。