相较数组而言,具有更好的空间效率。
单链表的各种操作:
有序单链表的插入一定要考虑清楚多种情况。
#include <stdio.h> #include <stdlib.h> #pragma warning (disable:4996) typedef struct link{ ///build an undirectional linked list int data; struct link* next; }LINK; struct link* AppendNode(struct link* head) { struct link *p = NULL, *pr = head; int data; p = (struct link*)malloc(sizeof(struct link)); if (p == NULL) { printf("No enough memory. "); exit(0); } if (head == NULL) head = p; else { while (pr->next != NULL) { pr = pr->next; } pr->next = p; } printf("Input a node data. "); scanf("%d", &data); p->data = data; p->next = NULL; return head; } void DisplayNode(struct link* head) { struct link* p = head; int j = 1; while (p != NULL) { printf("%5d%10d ", j, p->data); p = p->next; j++; } } void DeleteMemory(struct link* head) { struct link* p = NULL, * pr; p = head; while (p != NULL) { pr = p; free(pr); p = p->next; } } struct link* InsertNode(struct link* head, int nodeData) { struct link* p = head, * pr = head, * temp = NULL; p = (struct link*)malloc(sizeof(struct link)); if (p == NULL){ printf("No enough meomory! "); exit(0); } p->next = NULL; p->data = nodeData; if (head == NULL){ head = p; } else{ while (pr->data < nodeData && pr->next != NULL){ temp = pr; pr = pr->next; } if (pr->data >= nodeData){ if (pr == head){ p->next = head; head = p; } else{ pr = temp; p->next = pr->next; pr->next = p; } } else{ pr->next = p; } } return head; } struct link* DeleteOneNode(struct link* head, int delete) { struct link* p = head, * pr = NULL; if (p == NULL) { printf("No value to delete. "); exit(0); } while (p->next != NULL && p->data != delete) { pr = p; p = p->next; } if (p->next == NULL && p->data != delete) { printf("No such value to delete. "); exit(0); } else if (p == head) { head = p->next; } else { pr->next = p->next; } free(p); return head; } int main() { struct link* head = NULL; char c; int insert, delete; printf("Do you want to append a new node? "); scanf("%c", &c); while (c == 'y' || c == 'Y') { head = AppendNode(head); DisplayNode(head); printf("Do you want to append a new node? "); scanf(" %c", &c); } printf("Insert a number: "); scanf("%d", &insert); InsertNode(head, insert); DisplayNode(head); printf("Delete a number: "); scanf("%d", &delete); head = DeleteOneNode(head, delete); DisplayNode(head); DeleteMemory(head); return 0; }
一下是一个易犯的错误:
void DeleteMemory(LINK* head) { LINK* p = head; while (p != NULL) { free(p); p->fwd; } }
记住!释放内存后,旧指针就没有用了!
双链表:
基本操作同单链表,注意添加一个向前指的指针。
#include <stdio.h> #include <stdlib.h> #pragma warning (disable:4996) typedef struct LINK { struct LINK* fwd; struct LINK* bwd; int val; }LINK; LINK* initLINK(LINK* head) { LINK* p = NULL; head = (LINK*)malloc(sizeof(LINK)); if (head == NULL) { printf("No enough memory."); exit(0); } head->fwd = head->bwd = NULL; p = head; for (int i = 2; i <= 3; i++) { LINK* temp = (LINK*)malloc(sizeof(LINK)); if (temp == NULL) { printf("No enough memory."); exit(0); } p->fwd = temp; temp->bwd = p; temp->val = i - 1; p = p->fwd; } return head; } void displayNode(LINK* head) { LINK* p = head->fwd; while (p != NULL) { printf("%5d ", p->val); p = p->fwd; } } void deleteMemory(LINK* head) { LINK* p, *pr = NULL; p = head; while (p != NULL) { pr = p; free(pr); p = p->fwd; } } void insertNode(LINK* head, int fwd_val, int val) {//在某个数值前插入 一个节点 LINK* p = head->fwd, * pre, *node; node = (LINK*)malloc(sizeof(LINK)); if (node == NULL) { printf("No enough memory."); exit(0); } pre = p->bwd; while (p->val != fwd_val) { p = p->fwd; pre = p->bwd; } pre->fwd = node; node->fwd = p; node->bwd = pre; p->bwd = node; node->val = val; } int main() { LINK* head = NULL; head = initLINK(head); insertNode(head, 2, 4); displayNode(head); return 0; }
循环链表:
首先应注意构建链表时的规范,如尾节点next指针为NULL。
双向链表添加时注意双向可添加。