linkedList.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Node {
int data;
struct Node *next;
};
typedef struct Node *node;
node createNode(int val) {
node newNode = (node)malloc(sizeof(struct Node));
if (newNode == NULL) {
printf("cannot allocate memory");
exit(EXIT_FAILURE);
}
newNode->data = val;
newNode->next = NULL;
return newNode;
}
node insertFront(node head, int val) {
node insert = createNode(val);
if (head == NULL) {
head = insert;
return head;
}
insert->next = head;
head = insert;
return head;
}
node insertTail(node head, int val) {
node insert = createNode(val);
node temp = head;
if (head == NULL) {
head = insert;
return head;
}
while (temp->next != NULL)
temp = temp->next;
temp->next = insert;
insert->next = NULL;
return head;
}
node listSearch(node head, int val) {
node temp = head;
while (temp != NULL) {
if (temp->data == val) {
printf("%d\n", 1);
return temp;
}
temp = temp->next;
}
printf("%d\n", -1);
return NULL;
}
node insertAfter(node head, int afterThisVal, int val) {
node afterThis = listSearch(head, afterThisVal);
if (afterThis == NULL)
return head;
if (afterThis->next == NULL) {
head = insertTail(head, val);
return head;
}
node insert = createNode(val);
node temp = afterThis->next;
afterThis->next = insert;
insert->next = temp;
return head;
}
node insertBefore(node head, int beforeThisVal, int val) {
node beforeThis = listSearch(head, beforeThisVal);
if (beforeThis == NULL)
return head;
if (beforeThis == head) {
head = insertFront(head, val);
return head;
}
node prev = head;
while (prev->next != beforeThis)
prev = prev->next;
node insert = createNode(val);
prev->next = insert;
insert->next = beforeThis;
return head;
}
node deleteFirst(node head) {
if (head == NULL) {
printf("%d\n", -1);
return head;
}
node temp = head;
head = head->next;
printf("%d\n", temp->data);
free(temp);
return head;
}
node deleteLast(node head) {
if (head == NULL) {
printf("%d\n", -1);
return head;
}
node temp = head;
node prev = NULL;
while (temp->next != NULL) {
prev = temp;
temp = temp->next;
}
if (prev != NULL)
prev->next = NULL;
printf("%d\n", temp->data);
free(temp);
return head;
}
node deleteNode(node head, int val) {
node found = listSearch(head, val);
if (found == NULL) {
printf("%d\n",-1);
return head;
}
else if (found == head) {
head = deleteFirst(head);
return head;
}
else if (found->next == NULL) {
head = deleteLast(head);
return head;
}
node prev = head;
while (prev->next != found)
prev = prev->next;
prev->next = found->next;
printf("%d\n", found->data);
free(found);
return head;
}
void display(node head) {
if (head == NULL)
return;
node temp = head;
while (temp->next != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
printf("%d\n", temp->data);
}
node reverseList(node head) {
node i = head;
node j = NULL;
node k = NULL;
while (i != NULL) {
k = j;
j = i;
i = i->next;
j->next = k;
}
return j;
}
node reverseEven(node head) {
node oddHead = head;
node odd = head;
node evenHead = head->next;
node even = head->next;
node temp1 = NULL;
node temp2 = NULL;
while (odd->next != NULL && even->next != NULL) {
odd->next = even->next;
odd = odd->next;
even->next = odd->next;
even = even->next;
}
if ((odd != NULL && odd->next != NULL) || (even != NULL && even->next != NULL)) {
odd->next = NULL;
even->next = NULL;
}
display(evenHead);
display(oddHead);
evenHead = reverseList(evenHead);
even = evenHead;
odd = oddHead;
while (even != NULL && odd != NULL) {
temp1 = odd;
odd = odd->next;
temp1->next = even;
temp2 = even;
even = even->next;
temp2->next = odd;
}
return head;
}
int main() {
char op[2];
node head = NULL;
int inp1, inp2;
scanf("%s", op);
while (strcmp(op, "e") != 0) {
if (strcmp(op, "f") == 0) {
scanf("%d", &inp1);
head = insertFront(head, inp1);
display(head);
}
else if (strcmp(op, "t") == 0) {
scanf("%d", &inp1);
head = insertTail(head, inp1);
display(head);
}
else if (strcmp(op, "a") == 0) {
scanf("%d", &inp1);
scanf("%d", &inp2);
head = insertAfter(head, inp2, inp1);
display(head);
}
else if (strcmp(op, "b") == 0) {
scanf("%d", &inp1);
scanf("%d", &inp2);
head = insertBefore(head, inp2, inp1);
display(head);
}
else if (strcmp(op, "d") == 0) {
scanf("%d", &inp1);
head = deleteNode(head, inp1);
display(head);
}
else if (strcmp(op, "i") == 0) {
head = deleteFirst(head);
display(head);
}
else if (strcmp(op, "l") == 0 ){
head = deleteLast(head);
display(head);
}
else if (strcmp(op, "s") == 0) {
scanf("%d", &inp1);
listSearch(head, inp1);
}
else if (strcmp(op, "r") == 0) {
head = reverseList(head);
}
else if (strcmp(op, "ds") == 0) {
display(head);
}
else if (strcmp(op, "re") == 0) {
head = reverseEven(head);
}
else {
printf("INVALID\n");
}
scanf("%s", op);
}
return 1;
}
我的代码实现了链表的所有功能作为一个菜单驱动的程序。
input.txt:
f 7
t 10
a 11 7
b 12 11
d 10
i
l
s 12
s 6
t 15
f 14
f 20
ds
r
re
e
我看到的错误是分段错误。在input.txt中f 20
之后的ds
(显示函数),head随机获得一个垃圾值,并显示mingw_ovr _bulletin_va_lists部分我不确定我犯了什么错误。
请原谅我在代码中使用的不好的做法,因为我还在学习C。
1条答案
按热度按时间nhjlsmyf1#
函数
deleteLast
中有一个bug:你必须测试head
是否已经是最后一个节点,并在释放temp
后返回NULL
。当你在这之后从head
读取时,你有未定义的行为,因为你解引用了一个无效的指针。未定义的行为意味着任何事情都可能发生,包括不同运行或不同计算机上的不同行为。以下是修改后的版本:
在
main
中还有一个问题:将op
定义为2个char
的数组:这个数组只能存储一个字符串,最多一个字符和一个空字节,但是你用scanf("%s", op)
从用户那里读取,所以任何超过1个字符的输入字都会导致缓冲区溢出,因为scanf()
不知道目标数组有多长。您应该使数组更长,并告诉
scanf()
要存储到目标数组中的最大字符数,其长度介于%
和s
之间: