输入多个整数,以-1作为结束标志,顺序建立一个带头结点的单链表,之后对该单链表进行就地逆置(不增加新结点),并输出逆置后的单链表数据。c++最快做法
时间: 2023-08-31 12:19:57 浏览: 96
数据结构与算法 c++实现 //删除顺序递增表中的重复元素 //对单链表实现就地逆置 //删除递增单链表中的重复元素
5星 · 资源好评率100%
### 回答1:
以下是输入多个整数并建立单链表的代码:
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* next;
} Node;
Node* createList() {
Node* head = (Node*)malloc(sizeof(Node));
head->next = NULL;
Node* tail = head;
int num;
printf("请输入整数,以-1作为结束标志:\n");
while (1) {
scanf("%d", &num);
if (num == -1) {
break;
}
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = num;
newNode->next = NULL;
tail->next = newNode;
tail = newNode;
}
return head;
}
```
接下来是就地逆置单链表的代码:
```c
void reverseList(Node* head) {
Node* p = head->next;
Node* q = p->next;
p->next = NULL;
while (q != NULL) {
Node* r = q->next;
q->next = p;
p = q;
q = r;
}
head->next = p;
}
```
最后是输出逆置后的单链表数据的代码:
```c
void printList(Node* head) {
Node* p = head->next;
while (p != NULL) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
```
完整代码如下:
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* next;
} Node;
Node* createList() {
Node* head = (Node*)malloc(sizeof(Node));
head->next = NULL;
Node* tail = head;
int num;
printf("请输入整数,以-1作为结束标志:\n");
while (1) {
scanf("%d", &num);
if (num == -1) {
break;
}
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = num;
newNode->next = NULL;
tail->next = newNode;
tail = newNode;
}
return head;
}
void reverseList(Node* head) {
Node* p = head->next;
Node* q = p->next;
p->next = NULL;
while (q != NULL) {
Node* r = q->next;
q->next = p;
p = q;
q = r;
}
head->next = p;
}
void printList(Node* head) {
Node* p = head->next;
while (p != NULL) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int main() {
Node* head = createList();
reverseList(head);
printList(head);
return 0;
}
```
希望能帮到你!
### 回答2:
要实现最快的做法,首先需要考虑选择合适的数据结构。对于单链表,我们可以使用链表指针数组来代替传统的单链表结构,这样可以提高插入和删除结点的效率。
具体实现步骤如下:
1. 定义一个头结点和一个指针数组arr。
2. 初始化指针数组arr,使每个指针都指向头结点。
3. 读取输入的第一个整数num。
4. 如果num不等于-1,执行以下步骤:
- 创建一个新结点node,并将num赋值给新结点的data;
- 将新结点插入到链表的第一个位置中,即将新结点的指针指向头结点的指针所指向的结点,然后更新头结点的指针指向新结点;
- 更新头结点指针数组arr的指针,使其指向新结点。
- 读取下一个整数num。
5. 对链表进行就地逆置。遍历头结点指针数组arr,将结点的next指针指向前一个结点即可。
6. 输出逆置后的单链表数据。从头结点的next指针开始遍历链表,依次输出每个结点的data。
以下是一种实现方式:
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *next;
} Node;
int main() {
Node *head = (Node *) malloc(sizeof(Node));
Node **arr = (Node **) malloc(sizeof(Node *));
*arr = head;
int num;
scanf("%d", &num);
while (num != -1) {
Node *node = (Node *) malloc(sizeof(Node));
node->data = num;
node->next = *arr;
*arr = node;
scanf("%d", &num);
}
Node **cur = arr;
Node **prev = NULL;
while (*cur != head) {
Node *next = (*cur)->next;
(*cur)->next = *prev;
*prev = *cur;
*cur = next;
}
Node *temp = *prev;
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
return 0;
}
```
注意:为了提高效率,我们使用了指针指针,这会增加代码的复杂性。但是这种实现方式避免了频繁的结点插入和删除操作,提高了执行效率。
### 回答3:
首先创建一个带头结点的单链表,头结点的数据域可用来存放链表的长度。然后以循环方式读入整数,直到输入的整数为-1。每读入一个整数,就新建一个结点,将整数存入结点的数据域,并使结点成为当前链表的第一个结点,并更新头结点的数据域。这样就可以保证链表的顺序和长度随着输入的整数的增加而更新。
接下来进行就地逆置。从头结点的下一个结点开始,将每个结点依次插入到头结点之后,直到将整个链表反转。具体步骤如下:
1. 设置三个指针,分别指向当前结点、前一个结点和下一个结点。
2. 将当前结点的下一个结点保存为下一个结点。
3. 将当前结点的指针指向前一个结点。
4. 将前一个结点指向当前结点。
5. 将当前结点指向下一个结点。
6. 重复步骤2-5,直到将整个链表反转。
在上述操作之后,头结点的指针指向原链表的末尾,原链表的最后一个结点成为新链表的第一个结点。最后,按照链表的顺序输出每个结点的数据域即可。
下面是一个示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct ListNode {
int data;
struct ListNode* next;
} ListNode;
ListNode* createList() {
ListNode* head = (ListNode*)malloc(sizeof(ListNode));
head->data = 0;
head->next = NULL;
return head;
}
void insertNode(ListNode* head, int num) {
ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
newNode->data = num;
newNode->next = head->next;
head->next = newNode;
head->data++;
}
void reverseList(ListNode* head) {
ListNode* prev = NULL;
ListNode* current = head->next;
ListNode* next = NULL;
while (current != NULL) {
next = current->next;
current->next= prev;
prev = current;
current = next;
}
head->next = prev;
}
void printList(ListNode* head) {
ListNode* current = head->next;
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}
int main() {
ListNode* head = createList();
int num;
printf("请输入整数(以-1结束):");
scanf("%d", &num);
while (num != -1) {
insertNode(head, num);
scanf("%d", &num);
}
printf("输入的链表数据:");
printList(head);
reverseList(head);
printf("逆置后的链表数据:");
printList(head);
return 0;
}
```
该算法的时间复杂度为O(n),其中n为输入整数的个数。
阅读全文