Rezension für den persönlichen Gebrauch, keine Analyse.
Am Beispiel einer einseitig verknüpften Liste mit Sentinel-Knoten besteht das Ziel darin, die folgende Methode zu implementieren (teilweise wird auf den <list>-Container von C++ STL verwiesen):
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
typedef int ValType;
typedef struct node {
ValType val;
struct node *next;
} Node, List;
List* init(void); // 初始化链表
bool empty(List* head); // 判断链表为空
void clear(List* head); // 清空链表
void destroy(List* head); // 销毁链表
int size(List* head); // 链表大小
bool traverse(List* head); // 遍历链表
void pushFront(List* head, ValType val); // 头插法
void pushBack(List* head, ValType val); // 尾插法
ValType popFront(List* head); // 头出法
ValType popBack(List* head); // 尾出法
ValType front(List* head); // 头部元素
ValType back(List* head); // 尾部元素
bool insert(List* head, int n, ValType val); // 指定位置插入元素
ValType get(List* head, int n); // 获取指定位置元素
int match(List* head, ValType val); // 寻找匹配的元素
ValType delete(List* head, int n); // 删除指定位置元素
ValType deleteReverse(List *head, int n); // 反序删除指定位置元素
bool resize(List* head, int n); // 重新设置链表大小
bool reverse(List* head); // 翻转链表
bool sort(List* head); // 链表排序
bool unique(List* head); // 删除有序链表中的重复元素
List* splice(List* dest, List* src); // 拼接两个链表
List* merge(List* src1, List* src2); // 合并两个有序链表
Die spezifische Implementierung jeder Methode ist wie folgt:
Node* newNode(ValType val);
void quickSort(ValType arr[], int left, int right);
Node* newNode(ValType val) {
Node* node = (Node*)malloc(sizeof(Node));
node->val = val;
node->next = NULL;
return node;
}
List* init(void) {
List* head = newNode(-1);
return head;
}
bool empty(List* head) {
if (head->next == NULL) return true;
return false;
}
// 保留头节点
void clear(List* head) {
while (head->next) {
List* curr = head->next;
head->next = curr->next;
free(curr);
}
}
// 指针置空
void destroy(List* head) {
List* curr = head;
while (curr) {
head = head->next;
free(curr);
curr = head;
}
}
int size(List* head) {
int cnt = 0;
for (Node* curr = head->next; curr; curr = curr->next) ++cnt;
return cnt;
}
bool traverse(List* head) {
if (empty(head)) return false;
for (Node* curr = head->next; curr; curr = curr->next) {
printf("%d ", curr->val);
}
printf("\n");
return true;
}
void pushFront(List* head, ValType val) {
Node* curr = newNode(val);
curr->next = head->next;
head->next = curr;
}
// O(n)
void pushBack(List* head, ValType val) {
Node* tail = head;
while (tail->next) tail = tail->next;
tail->next = newNode(val);
}
ValType popFront(List* head) {
if (empty(head)) return -1;
Node* curr = head->next;
head->next = curr->next;
ValType val = curr->val;
free(curr);
return val;
}
// O(n)
ValType popBack(List* head) {
if (empty(head)) return -1;
Node* prev = head;
while (prev->next->next) prev = prev->next;
ValType val = prev->next->val;
free(prev->next);
prev->next = NULL;
return val;
}
ValType front(List* head) {
if (empty(head)) return -1;
return head->next->val;
}
// O(n)
ValType back(List* head) {
if (empty(head)) return -1;
Node* tail = head;
while (tail->next) tail = tail->next;
return tail->val;
}
// 遍历到满足条件的前一个节点
bool insert(List* head, int n, ValType val) {
if (empty(head) || n < 1) return false;
for (Node* prev = head; prev->next; prev = prev->next) {
--n;
if (n == 0) {
Node* new = newNode(val);
new->next = prev->next;
prev->next = new;
return true;
}
} return false;
}
ValType get(List* head, int n) {
if (empty(head) || n < 1) return -1;
for (Node* curr = head->next; curr->next; curr = curr->next) {
--n;
if (n == 0) {
return curr->val;
}
} return -1;
}
int match(List* head, ValType val) {
if (empty(head)) return -1;
int cnt = 0;
for (Node* curr = head->next; curr->next; curr = curr->next) {
++cnt;
if (curr->val == val) return cnt;
} return -1;
}
// 遍历到满足条件的前一个节点
ValType delete(List* head, int n) {
if (empty(head) || n < 1) return -1;
for (Node* prev = head; prev->next; prev = prev->next) {
--n;
if (n == 0) {
Node* del = prev->next;
prev->next = del->next;
ValType val = del->val;
free(del);
return val;
}
} return -1;
}
// 双指针法
ValType deleteReverse(List *head, int n) {
if (empty(head) || n < 1) return -1;
Node* fast = head->next;
for (int i = n - 1; i > 0; --i) {
if (fast->next == NULL) return -1;
fast = fast->next;
}
Node* slow = head;
while (fast->next) {
fast = fast->next;
slow = slow->next;
}
Node* curr = slow->next;
slow->next = curr->next;
ValType val = curr->val;
free(curr);
return val;
}
// 遍历到满足条件的前一个节点
bool resize(List* head, int n) {
if (empty(head) || n < 1) return false;
for (Node* prev = head; prev->next; prev = prev->next) {
--n;
if (n == 0) {
clear(prev->next);
return true;
}
} return false;
}
// 三指针迭代法
bool reverse(List* head) {
if (empty(head) || empty(head->next)) return false;
Node *prev = NULL, *curr = head->next;
while (curr) {
Node* next = curr->next;
curr->next = prev;
prev = curr, curr = next;
}
head->next = prev;
return true;
}
// 传入数组使用快排
bool sort(List* head) {
if (empty(head) || empty(head->next)) return false;
int arrSize = size(head);
ValType* arr = (ValType*)malloc(sizeof(ValType) * arrSize);
Node* curr = head->next;
for (int i = 0; i < arrSize; ++i) {
arr[i] = curr->val;
curr = curr->next;
}
quickSort(arr, 0, arrSize - 1);
curr = head->next;
for (int i = 0; i < arrSize; ++i) {
curr->val = arr[i];
curr = curr->next;
}
free(arr);
return true;
}
// 遍历到重复值出现的前一个节点
bool unique(List* head) {
if (empty(head) || empty(head->next)) return false;
Node* prev = head->next;
while (prev->next->next) {
if (prev->val > prev->next->val) {
return false;
} else if (prev->val == prev->next->val) {
Node* curr = prev->next;
prev->next = curr->next;
free(curr);
} else {
prev = prev->next;
}
} return true;
}
List* splice(List* dest, List* src) {
if (empty(dest)) return src;
if (empty(src)) return dest;
Node* tail = dest;
while (tail->next) tail = tail->next;
tail->next = src->next;
return dest;
}
List* merge(List* src1, List* src2) {
if (empty(src1)) return src2;
if (empty(src2)) return src1;
sort(src1), sort(src2);
List* dest = init();
Node *curr1 = src1->next, *curr2 = src2->next, *tail = dest;
while (curr1 && curr2) {
if (curr1->val < curr2->val) {
tail->next = curr1;
curr1 = curr1->next;
tail = tail->next;
} else {
tail->next = curr2;
curr2 = curr2->next;
tail = tail->next;
}
}
// 将剩余部分直接连接
if (curr1) tail->next = curr1;
if (curr2) tail->next = curr2;
src1->next = NULL, src2->next = NULL;
return dest;
}
void quickSort(int arr[], int left, int right) {
if (left >= right) return;
srand(time(NULL));
int idx = rand() % (left - right) + left;
int flag = arr[idx], head = left - 1, tail = right + 1;
while (head < tail) {
do head++; while(arr[head] < flag);
do tail--; while(arr[tail] > flag);
if (head < tail) {
int tmp = arr[head];
arr[head] = arr[tail];
arr[tail] = tmp;
}
}
quickSort(arr, left, tail);
quickSort(arr, tail + 1, right);
}
Testfall:
void test1();
void test2();
void test1() {
List* list = init();
pushBack(list, 4);
pushBack(list, 5);
pushBack(list, 6);
pushFront(list, 3);
pushFront(list, 2);
pushFront(list, 1);
traverse(list);
printf("%d %d %d\n", size(list), front(list), back(list));
printf("%d %d %d\n", get(list, 3), match(list, 5), match(list, 10));
insert(list, 3, 0);
traverse(list);
deleteReverse(list, 5);
traverse(list);
delete(list, 2);
traverse(list);
printf("%d %d\n", popFront(list), popBack(list));
traverse(list);
pushFront(list, 2);
pushBack(list, 6);
pushBack(list, 7);
traverse(list);
resize(list, 4);
traverse(list);
reverse(list);
traverse(list);
clear(list);
printf("%d\n", size(list));
destroy(list);
printf("\n");
return;
}
void test2() {
List* list = init();
pushFront(list, 2);
pushFront(list, 4);
pushFront(list, 9);
pushFront(list, 11);
pushFront(list, 2);
pushFront(list, 10);
pushFront(list, 2);
pushFront(list, 8);
pushFront(list, 1);
pushFront(list, 12);
pushFront(list, 3);
pushFront(list, 2);
pushFront(list, 11);
pushFront(list, 14);
pushFront(list, 4);
pushFront(list, 2);
traverse(list);
sort(list);
traverse(list);
unique(list);
traverse(list);
List* list2 = init();
pushFront(list2, 9);
pushFront(list2, 7);
pushFront(list2, 7);
pushFront(list2, 3);
pushFront(list2, 2);
traverse(list2);
List* list3 = merge(list, list2);
traverse(list3);
}