📅  最后修改于: 2023-12-03 15:41:31.584000             🧑  作者: Mango
本文介绍了如何使用菜单驱动程序来实现双循环链表的所有操作。
双循环链表是一种链式存储结构,它由若干个结点组成,每个结点包含两个指针域,一个指向前驱结点,一个指向后继结点。它的最后一个结点的后继指针指向头结点,头结点的前驱指针指向最后一个结点,因此形成一个双向循环链表。
菜单驱动程序是一种交互式程序设计技术,它通过显示一个菜单列表让用户选择操作,然后执行用户选择的操作。菜单驱动程序可以被用来实现任何需要用户选择操作的程序,包括双循环链表操作。
以下是我们将要实现的双循环链表操作菜单列表:
== 双循环链表操作菜单 ==
1. 创建双循环链表
2. 插入结点
3. 删除结点
4. 查找结点
5. 显示双循环链表
6. 退出程序
该菜单列表包含了以下操作:
我们将分别实现这些操作。
用户可以在菜单列表中选择创建双循环链表操作。该操作将创建一个空的双循环链表。
以下是创建双循环链表的代码片段:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* prev;
struct Node* next;
} Node;
Node* createDLList() {
Node* head = (Node*) malloc(sizeof(Node));
head->prev = head;
head->next = head;
return head;
}
int main() {
Node* head = createDLList();
// ...
return 0;
}
该函数返回一个指针,指向创建的双循环链表的头结点。
用户可以在菜单列表中选择插入结点操作。该操作将在指定位置插入一个新结点。
以下是插入结点的代码片段:
void insert(Node* head, int pos, int data) {
if (pos < 0) {
printf("Invalid position!\n");
return;
}
Node* p = head;
for (int i = 0; i < pos; i++) {
p = p->next;
if (p == head) {
printf("Out of range!\n");
return;
}
}
Node* q = (Node*) malloc(sizeof(Node));
q->data = data;
q->prev = p;
q->next = p->next;
p->next->prev = q;
p->next = q;
}
int main() {
// ...
insert(head, 0, 42);
// ...
return 0;
}
该函数接受三个参数:双循环链表的头结点,插入位置和插入的数据。如果插入位置超出了双循环链表的范围,该函数将不进行任何操作。
用户可以在菜单列表中选择删除结点操作。该操作将删除指定位置的结点。
以下是删除结点的代码片段:
void delete(Node* head, int pos) {
if (pos < 0) {
printf("Invalid position!\n");
return;
}
Node* p = head;
for (int i = 0; i < pos; i++) {
p = p->next;
if (p == head) {
printf("Out of range!\n");
return;
}
}
p->next->prev = p->prev;
p->prev->next = p->next;
free(p);
}
int main() {
// ...
delete(head, 0);
// ...
}
该函数接受两个参数:双循环链表的头结点和要删除的结点的位置。如果删除位置超出了双循环链表的范围,该函数将不进行任何操作。
用户可以在菜单列表中选择查找结点操作。该操作将在双循环链表中查找指定的数据,并返回该结点的位置。
以下是查找结点的代码片段:
int search(Node* head, int data) {
Node* p = head->next;
int i = 0;
while (p != head) {
if (p->data == data) {
return i;
}
p = p->next;
i++;
}
return -1;
}
int main() {
// ...
int pos = search(head, 42);
// ...
return 0;
}
该函数接受两个参数:双循环链表的头结点和要查找的数据。如果找到了该数据,该函数将返回该结点的位置,否则将返回 -1。
用户可以在菜单列表中选择显示双循环链表操作。该操作将显示双循环链表的所有结点。
以下是显示双循环链表的代码片段:
void display(Node* head) {
Node* p = head->next;
while (p != head) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int main() {
// ...
display(head);
// ...
return 0;
}
该函数接受一个参数:双循环链表的头结点。该函数将遍历双循环链表,并打印出每个结点的数据。
下面是实现以上操作的完整代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* prev;
struct Node* next;
} Node;
Node* createDLList() {
Node* head = (Node*) malloc(sizeof(Node));
head->prev = head;
head->next = head;
return head;
}
void insert(Node* head, int pos, int data) {
if (pos < 0) {
printf("Invalid position!\n");
return;
}
Node* p = head;
for (int i = 0; i < pos; i++) {
p = p->next;
if (p == head) {
printf("Out of range!\n");
return;
}
}
Node* q = (Node*) malloc(sizeof(Node));
q->data = data;
q->prev = p;
q->next = p->next;
p->next->prev = q;
p->next = q;
}
void delete(Node* head, int pos) {
if (pos < 0) {
printf("Invalid position!\n");
return;
}
Node* p = head;
for (int i = 0; i < pos; i++) {
p = p->next;
if (p == head) {
printf("Out of range!\n");
return;
}
}
p->next->prev = p->prev;
p->prev->next = p->next;
free(p);
}
int search(Node* head, int data) {
Node* p = head->next;
int i = 0;
while (p != head) {
if (p->data == data) {
return i;
}
p = p->next;
i++;
}
return -1;
}
void display(Node* head) {
Node* p = head->next;
while (p != head) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int main() {
Node* head = createDLList();
printf("== 双循环链表操作菜单 ==\n");
printf("1. 创建双循环链表\n");
printf("2. 插入结点\n");
printf("3. 删除结点\n");
printf("4. 查找结点\n");
printf("5. 显示双循环链表\n");
printf("6. 退出程序\n");
int choice, pos, data, index;
while (1) {
printf("请选择操作:");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("创建双循环链表\n");
break;
case 2:
printf("插入结点\n");
printf("请输入要插入的位置:");
scanf("%d", &pos);
printf("请输入要插入的数据:");
scanf("%d", &data);
insert(head, pos, data);
break;
case 3:
printf("删除结点\n");
printf("请输入要删除的位置:");
scanf("%d", &pos);
delete(head, pos);
break;
case 4:
printf("查找结点\n");
printf("请输入要查找的数据:");
scanf("%d", &data);
index = search(head, data);
if (index == -1) {
printf("未找到该数据\n");
} else {
printf("该数据在第 %d 个位置\n", index);
}
break;
case 5:
printf("显示双循环链表\n");
display(head);
break;
case 6:
printf("退出程序\n");
return 0;
default:
printf("无效的操作\n");
break;
}
}
}
在本文中,我们学习了如何使用菜单驱动程序来实现双循环链表的所有操作,包括创建双循环链表、插入结点、删除结点、查找结点和显示双循环链表。菜单驱动程序可以方便地让用户进行交互操作,使程序更加友好。