背景
- 链表可以看作是可变数组的另外一种实现,通过指向新空间的方式,减少内存浪费,以及不用拷贝旧数据。
- 通过自定函数封装相关功能,方便使用。
- 双结构体,即除了创建节点结构体(Node)之外,还创建了一个链表结构体(Linked_List)可以方便进行节点管理,以及增强拓展性。
- 本文中的具体实现参考了浙大翁恺老师的 C 语言课程,链接已在本文末尾给出,如果有地方看不懂可以自己去看视频了解或者私信我。
结构定义及相关函数声明(linked_list_double.h)
#ifndef __LINKED_LIST_DOUBLE_H
#define __LINKED_LIST_DOUBLE_H
typedef struct Node {
int value_;
struct Node *next_;
} Node;
typedef struct Linked_List {
Node *head_;
Node *tail_;
} Linked_List;
void node_Add(Linked_List *list, int value);
void node_Delete(Linked_List *list, int target);
void node_Set(Linked_List *list, int old_value, int new_value);
Node* node_Search(const Linked_List *list, int target);
void node_Linked_List_Print(Linked_List *list);
void node_Linked_List_Clear(Linked_List *list);
#endif
函数定义(linked_list_double.c)
#include <stdio.h>
#include <stdlib.h>
#include "linked_list_double.h"
void node_Add(Linked_List *list, int value){
Node *new_node = (Node*)malloc(sizeof(Node));
new_node -> value_ = value;
new_node -> next_ = (Node*)malloc(sizeof(Node));
*(list -> tail_) = *new_node;
list -> tail_ = new_node -> next_;
}
void node_Delete(Linked_List *list, int target) {
Node *tp = list -> head_, *temp = tp -> next_;
if (list -> head_ -> value_ == target) {
free(tp);
list -> head_ = temp;
} else {
while (1) {
if (temp -> value_ == target) {
tp -> next_ = temp -> next_;
free(temp);
break;
} else if (temp == list -> tail_) {
break;
}
tp = temp;
temp = temp -> next_;
}
}
}
void node_Set(Linked_List *list, int old_value, int new_value) {
node_Search(list, old_value) -> value_ = new_value;
}
Node* node_Search(const Linked_List *list, int target) {
Node *tp = list -> head_;
while (1) {
if (tp -> value_ == target) {
break;
} else if (tp -> next_ == list -> tail_) {
printf("没有指定节点,请重试!(返回头节点地址)\n");
tp = list -> head_;
break;
}
tp = tp -> next_;
}
return tp;
}
void node_Linked_List_Print(Linked_List *list) {
Node *tp = list -> head_;
for (int i = 1; tp != list -> tail_; tp = tp -> next_, i++) {
printf("%d ", tp -> value_);
if (i % 5 == 0) {
printf("\n");
}
}
printf("\n");
}
void node_Linked_List_Clear(Linked_List *list) {
Node *tp = list -> head_, *temp = tp -> next_;
while (1) {
free(tp);
tp = temp;
if (temp == list -> tail_) {
free(temp);
break;
} else {
temp = temp -> next_;
}
}
}
测试(main.c)
#include <stdio.h>
#include <stdlib.h>
#include "linked_list_double.h"
int main() {
Node *head = (Node*)malloc(sizeof(Node));
Linked_List list = {head, head};
int number = 0, value = 0;
while (1) {
scanf("%d", &number);
if (number == -1) {
break;
} else {
node_Add(&list, number);
}
}
printf("当前列表的所有数据节点:\n");
node_Linked_List_Print(&list);
printf("请输入要删除的节点数据:");
scanf("%d", &value);
node_Delete(&list, value);
printf("请输入要设置的节点数据及新数据:");
scanf("%d %d", &number, &value);
node_Set(&list, number, value);
printf("当前列表的所有数据节点:\n");
node_Linked_List_Print(&list);
node_Linked_List_Clear(&list);
system("pause");
return 0;
}
参考资料
C 语言程序设计进阶-翁恺