c语言实现:链表创建、插入、删除、翻转
#include <stdio.h>
#include <stdlib.h>// 链表创建
typedef struct Node{int data;struct Node* next;
} Node;// 创建一个节点
Node* createNode(int data){Node* newNode = (Node* )malloc(sizeof(Node));newNode->data = data;newNode->next = NULL;return newNode;
}// 创建并插入一个节点
void insertNode(Node* head, int data){ // 要修改head得传入地址Node* insert = createNode(data);insert->next = head->next;head->next = insert;
}// 打印链表
void nodeListPrint(Node* head){int index = 0;head = head->next;while(head != NULL){printf("index: %d, head->data: %d\n", index, head->data);head = head->next;index ++;}
}// 根据data的值获取节点
Node* getNodeByData(Node* head, int data){while(head != NULL){if(head->data == data) return head;head = head->next;}printf("no wish node: %d\n", data);return NULL;
}// 根据data的值删除节点
void deleteNodeByData(Node* head, int data){Node* delete = getNodeByData(head, data);if(delete == NULL) return;while(head != NULL && head->next != delete) head = head->next;head->next = delete->next;delete->next = NULL;free(delete);
}// 链表翻转
void nodeListReverse(Node** head){Node* nodehead = *head; Node* oldhead = (*head)->next;Node* next = NULL;*head = NULL;while(oldhead != NULL){next = oldhead->next;oldhead->next = *head;*head = oldhead;oldhead = next;}nodehead->next = *head;*head = nodehead;
}int main(){Node* head = (Node* )malloc(sizeof(Node)); // 创建头节点for(int i = 1; i <= 10; i ++) insertNode(head, i);printf("1.完整链表如下:\n");nodeListPrint(head);printf("2.删除后的链表如下:\n");deleteNodeByData(head, 2);deleteNodeByData(head, 6);nodeListPrint(head);printf("3.链表翻转如下:\n");nodeListReverse(&head);nodeListPrint(head);printf("4.删除后的链表如下:\n");deleteNodeByData(head, 7);deleteNodeByData(head, 8);nodeListPrint(head);return 0;}
其中链表翻转也可以不用二阶指针,但是需要做返还在主函数要接收
// 链表翻转一阶指针
Node* nodeListReverse1(Node* head){Node* nodehead = head;Node* nhead = NULL;Node* next = NULL;head = head->next;while(head != NULL){next = head->next;head->next = nhead;nhead = head;head = next;}nodehead->next = nhead;nhead = nodehead;return nhead;
}
结果仍然是一样的
其他补充:
Makefile可以这样写:
runm: clean MAIN./MAINMAIN: main.ogcc -o MAIN main.omain.o: main.cgcc -c main.c -o main.oclean:rm -f *.o MAIN TESTrunt: clean TEST./TESTTEST: test.ogcc -o TEST test.otest.o: test.cgcc -c test.c -o test.o
优化后如下所示:
TRV1 = MAIN
TRV2 = TEST
TEP1 = main.o
TEP2 = test.o
ORG1 = main.c
ORG2 = test.crunm: clean $(TRV1)./$(TRV1)$(TRV1): $(TEP1)gcc -o $@ $<$(TEP1): $(ORG1)gcc -c $< -o $@clean:rm -f *.o MAIN TESTrunt: clean $(TRV2)./$(TRV2)$(TRV2): $(TEP2)gcc -o $@ $<$(TEP2): $(ORG2)gcc -c $< -o $@