c
复制代码
#include <stdlib.h>
#include <stdio.h>
typedef struct ListTable {
struct ListTable* next;
int val;
};
ListTable* createNode(int val) {
ListTable* node = (ListTable*)malloc(sizeof(ListTable));
if (node == NULL) return NULL;
node->next = NULL;
node->val = val;
return node;
}
// 《=========================增=========================》
// 头不存数据
bool insertHead(ListTable* head, int val) {
if (!head) return false;
ListTable* node = createNode(val);
if (!node) return false;
ListTable* p = head;
ListTable* temp = NULL;
temp = p->next;
p->next = node;
node->next = temp;
return true;
}
bool insertTail(ListTable* head, int val) {
if (!head) return false;
ListTable* node = createNode(val);
if (!node) return false;
ListTable* p = head;
while (p->next) {
p = p->next;
}
p->next = node;
return true;
}
bool insertPos(ListTable* head, int pos, int val) {
if (!head || pos == 0) return false;
ListTable* p = head;
int count = 0;
while (count != (pos - 1) || !p) {
if (p->next)
p = p->next;
else
break;
++count;
}
if (count != (pos - 1)) return false;
ListTable* node = createNode(val);
if (!node) return false;
ListTable* temp = p->next;
p->next = node;
node->next = temp;
return true;
}
// 《=========================删=========================》
bool deleteByPos(ListTable* head, int pos) {
if (!head || !head->next || pos == 0) return false;
ListTable* p = head->next;
ListTable* pre = head;
int count = 1;
while (p && count != pos) {
if (!p->next) break;
pre = pre->next;
p = p->next;
++count;
}
if (count != pos) return false;
pre->next = p->next;
free(p);
return true;
}
bool deleteNodeByVal(ListTable* head, int val) {
if (!head && !head->next) return false;
ListTable* p = head->next;
ListTable* pre = head;
while (p) {
if (p->val == val) {
pre->next = p->next;
free(p);
p = pre->next;
continue;
}
if (!p->next) break;
pre = pre->next;
p = p->next;
}
return true;
}
// 《=========================查=========================》
ListTable* findNodeByPos(ListTable* head, int pos) {
if (!head) return NULL;
ListTable* p = head;
int count = 0;
while (p && count != pos) {
if (!p->next) break;
p = p->next;
++count;
}
if (count != pos) return NULL;
return p;
}
ListTable* findNodeByVal(ListTable* head, int val) {
if (!head) return NULL;
ListTable* p = head;
while (p) {
if (p->val == val) return p;
if (!p->next) break;
p = p->next;
}
return NULL;
}
// 《=========================改=========================》
bool modifyNodeByPos(ListTable* head, int pos, int val) {
if (!head || pos == 0) return false;
ListTable* p = head;
int count = 0;
while (p && (count != pos)) {
if (!p->next) break;
p = p->next;
++count;
}
if (count != pos) return false;
p->val = val;
return true;
}
bool modifyNodeByVal(ListTable* head, int src_val, int dst_val) {
if (!head) return false;
ListTable* p = head;
while (p) {
if (p->val == src_val) {
p->val = dst_val;
}
p = p->next;
}
return true;
}
// 《=========================遍历=========================》
void printListTable(ListTable* head) {
if (!head) return;
ListTable* p = head;
printf("遍历链表:");
while (p) {
printf("%d ", p->val);
p = p->next;
}
}
// 《=========================释放=========================》
void deleteListTable(ListTable* head) {
if (!head) return;
ListTable* temp = NULL;
while (head) {
temp = head->next;
free(head);
head = temp;
}
}
/* ================== 测试辅助 ================== */
#define ASSERT_TRUE(expr, msg) \
do { if (!(expr)) { printf("[FAIL] %s (表达式: %s)\n", msg, #expr); ++failCount; } else { ++passCount; } } while(0)
static int passCount = 0;
static int failCount = 0;
int lengthWithoutDummy(ListTable* head) {
if (!head) return 0;
int len = -1; // 头结点不算数据
ListTable* p = head;
while (p) {
++len;
p = p->next;
}
return len < 0 ? 0 : len;
}
int getValueAt(ListTable* head, int pos) { // pos 从 1 开始(跳过头结点)
if (!head || pos <= 0) return -99999;
ListTable* p = head->next;
int idx = 1;
while (p && idx < pos) {
p = p->next;
++idx;
}
return (p && idx == pos) ? p->val : -99999;
}
void rebuild(ListTable** headPtr) {
deleteListTable(*headPtr);
*headPtr = createNode(0); // dummy
}
/* =============== MAIN: 综合测试用例 =============== */
int main(void) {
printf("开始链表单元测试...\n");
ListTable* head = createNode(0);
ASSERT_TRUE(head != NULL, "创建头结点");
// 1. 头插测试
for (int i = 1; i <= 5; ++i) {
ASSERT_TRUE(insertHead(head, i), "insertHead 成功");
}
ASSERT_TRUE(lengthWithoutDummy(head) == 5, "头插后长度=5");
ASSERT_TRUE(getValueAt(head, 1) == 5, "头插后第1个元素=5");
ASSERT_TRUE(getValueAt(head, 5) == 1, "头插后第5个元素=1");
// 2. 尾插测试
for (int i = 10; i <= 13; ++i) {
ASSERT_TRUE(insertTail(head, i), "insertTail 成功");
}
ASSERT_TRUE(lengthWithoutDummy(head) == 9, "头+尾插后长度=9");
ASSERT_TRUE(getValueAt(head, 9) == 13, "最后一个元素=13");
printListTable(head);
// 3. 按位置插入(有效位置)
ASSERT_TRUE(insertPos(head, 1, 100), "位置1插入 100");
ASSERT_TRUE(getValueAt(head, 1) == 100, "位置1元素=100");
ASSERT_TRUE(insertPos(head, 5, 200), "位置5插入 200");
ASSERT_TRUE(getValueAt(head, 5) == 200, "位置5元素=200");
// 4. 按位置插入(非法位置)
ASSERT_TRUE(!insertPos(head, 999, 300), "非法位置插入失败");
printListTable(head);
// 5. 按位置修改
ASSERT_TRUE(modifyNodeByPos(head, 1, 101), "修改位置1为101");
ASSERT_TRUE(getValueAt(head, 1) == 101, "验证修改位置1=101");
// 6. 按值批量修改(将所有 10 改为 88)
ASSERT_TRUE(modifyNodeByVal(head, 10, 88), "按值修改 10->88");
ListTable* found10 = findNodeByVal(head, 10);
ASSERT_TRUE(found10 == NULL, "值10已全部替换");
ASSERT_TRUE(findNodeByVal(head, 88) != NULL, "找到替换后的 88");
// 7. 查找(按位置 / 按值)
ListTable* nodePos5 = findNodeByPos(head, 5);
ASSERT_TRUE(nodePos5 != NULL, "findNodeByPos(5) 存在");
ListTable* nodeVal200 = findNodeByVal(head, 200);
ASSERT_TRUE(nodeVal200 != NULL && nodeVal200->val == 200, "findNodeByVal(200) 找到");
// 8. 删除指定位置
int beforeLen = lengthWithoutDummy(head);
ASSERT_TRUE(deleteByPos(head, 5), "删除位置5");
ASSERT_TRUE(lengthWithoutDummy(head) == beforeLen - 1, "长度减少1");
ASSERT_TRUE(getValueAt(head, 5) != 200, "原位置5的200被删除");
// 9. 删除指定值(删除所有 88)
ASSERT_TRUE(deleteNodeByVal(head, 88), "删除值 88");
ASSERT_TRUE(findNodeByVal(head, 88) == NULL, "88 不再存在");
printListTable(head);
// 10. 边界:删除不存在位置
ASSERT_TRUE(!deleteByPos(head, 999), "删除不存在位置失败");
// 11. 重建 + 空链表操作
rebuild(&head);
ASSERT_TRUE(lengthWithoutDummy(head) == 0, "重建后长度=0");
ASSERT_TRUE(findNodeByPos(head, 1) == NULL, "空链表 findNodeByPos(1)=NULL");
ASSERT_TRUE(!deleteByPos(head, 1), "空链表 deleteByPos(1) 失败");
ASSERT_TRUE(modifyNodeByVal(head, 1, 2), "空链表按值修改安全返回");
// 12. 单元素删除
ASSERT_TRUE(insertTail(head, 555), "插入单元素 555");
ASSERT_TRUE(lengthWithoutDummy(head) == 1, "长度=1");
ASSERT_TRUE(deleteByPos(head, 1), "删除唯一元素");
ASSERT_TRUE(lengthWithoutDummy(head) == 0, "删除后长度=0");
ASSERT_TRUE(findNodeByVal(head, 555) == NULL, "值555不存在");
deleteListTable(head);
head = NULL;
printf("\n测试结束: 通过 %d 项, 失败 %d 项\n", passCount, failCount);
if (failCount == 0) {
printf("所有测试通过。\n");
}
else {
printf("存在失败,请检查实现。\n");
}
return failCount == 0 ? 0 : 1;
}