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;
}
我的代码将链表的所有功能实现为菜单驱动程序。
输入.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(display function) 处,head 随机获取一个垃圾值,它显示 mingw_ovr _bulletin_va_lists 部分 我不确定我犯了什么错误。
请原谅我在代码中可能使用的不好的做法,因为我仍在学习 C。
函数
deleteLast
有一个bug:必须测试head
是否已经是最后一个节点,并在释放NULL
后返回temp
。当您取消引用无效指针时,在此之后读取 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) {
head = NULL;
} else {
prev->next = NULL;
}
printf("%d\n", temp->data);
free(temp);
return head;
}