源码
直接编译完成验证
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//定义双链表节点
struct node {
int data ;
struct node *prenode ;
struct node *nextnode ;
};
//创建新节点的函数
struct node *create_node(int node_value )
{
struct node * new_node = malloc(sizeof(struct node)) ;
//检查内存分配
if(new_node == NULL)
{
printf("内存分配失败!\n");
return NULL;
}
//初始化节点
new_node->data = node_value ;
new_node->prenode = NULL ;
new_node->nextnode = NULL ;
printf("创建节点成功,数据 = %d,地址 = %p\n", new_node->data, new_node);
return new_node ;
}
//连接节点,形成双链表
void connect_node(struct node *first_node,struct node *second_node)
{
if (first_node == NULL || second_node == NULL) {
printf("错误:节点不能为空!\n");
return;
}
first_node->nextnode = second_node ;
second_node->prenode = first_node ;
}
//创建链表管理结构,为了更好地管理链表
struct DoublyLinkList{
struct node *head;//头节点
struct node *tail;//尾节点
int size ;//链表大小
};
//初始化链表
struct DoublyLinkList* create_none_list() {
struct DoublyLinkList* list = (struct DoublyLinkList*)malloc(sizeof(struct DoublyLinkList));
list->head = NULL;
list->tail = NULL;
list->size = 0;
printf("创建了新的空链表\n");
return list;
}
//插入节点到指定位置,eg:position == 2:新节点作为第2个几点
void add_node_in_list(struct DoublyLinkList* list, int position, int node_value)
{
struct node * new_node = create_node(node_value);
if(position > list->size)//超过链表大小,就插入尾节点
{
printf("超过链表大小,就插入尾节点\n");
if(list->head == NULL)// 链表为空,新节点既是头也是尾
{
printf("新的空链表\n");
list->head = new_node ;
list->tail = new_node ;
}
else{// 链表不为空,添加到尾部
printf("不是空链表\n");
list->tail->nextnode = new_node ;//新节点传给为节点的next域
new_node->prenode = list->tail ;
list->tail = new_node ; //尾节点跳至新节点地址
}
}
else
{
struct node * current_node = list->head ;
for(int i = position ; i > 2 ; i--)
{
current_node = current_node->nextnode ;
}
printf("加在 %p:%d 节点后\n",current_node,current_node->data);
new_node->nextnode = current_node->nextnode ;//新节点的下一个节点地址给到新节点的next域
current_node->nextnode->prenode = new_node ;//新节点的下一个节点的pre域指向新节点地址
new_node->prenode = current_node ; //新节点的pre域指向前一个节点地址
current_node->nextnode = new_node ;//新节点给到前一个节点的next域
}
list->size++;
printf("链表size大小变为:%d\n",list->size);
}
//在链表尾部添加节点
void append_node(struct DoublyLinkList* list , int node_value)
{
struct node * new_node = create_node(node_value);
if(list->head == NULL)// 链表为空,新节点既是头也是尾
{
printf("新的空链表\n");
list->head = new_node ;
list->tail = new_node ;
}
else{// 链表不为空,添加到尾部
printf("不是空链表\n");
list->tail->nextnode = new_node ;//新节点传给为节点的next域
new_node->prenode = list->tail ;
list->tail = new_node ; //尾节点跳至新节点地址
}
list->size++ ;
printf("链表大小为:%d\n",list->size);
}
//在链表头部添加节点
void preappend_node(struct DoublyLinkList* list ,int node_value)
{
struct node * new_node = create_node(node_value);
if(list->head == NULL)// 链表为空,新节点既是头也是尾
{
printf("新的空链表\n");
list->head = new_node ;
list->tail = new_node ;
}
else{// 链表不为空,添加到尾部
printf("不是空链表\n");
list->head->prenode = new_node ;//新节点传给为节点的pre域
new_node->nextnode = list->head ;
list->head = new_node ; //尾节点跳至新节点地址
}
list->size++ ;
printf("链表大小为:%d\n",list->size);
}
//删除指定位置的节点
void delete_local_node(struct DoublyLinkList* list , int position )
{
if(position > list->size)
{
printf("超过链表大小\n");
return ;
}
struct node * current_node = list->head ;
struct node * tmp_node = NULL ;
for(int i = position ; i > 1 ; i--)
{
current_node = current_node->nextnode ;
}
printf("被删除节点地址为:%p\n",current_node);
tmp_node = current_node ; //要被释放的节点
printf("被释放的节点地址为:%p\n",tmp_node);
current_node->prenode->nextnode = current_node->nextnode ;//把删除节点的下一个节点地址给到删除节点上一个节点的next域
current_node->nextnode->prenode = current_node->prenode ;//把删除节点的前一个节点的地址给到删除节点的下一个节点的pre域
free(tmp_node);
list->size--;
printf("释放结束,size大小为:%d\n",list->size);
}
//删除头节点
void delete_head_node(struct DoublyLinkList* list )
{
if(list == NULL)
{
printf("链表为空\n");
return ;
}
struct node * current_node = list->head ;
struct node * tmp_node = NULL ;
printf("被删除节点地址为:%p\n",current_node);
tmp_node = current_node ; //要被释放的节点
printf("被释放的节点地址为:%p\n",tmp_node);
list->head = current_node->nextnode ;//下一个节点给到头结点
current_node->nextnode->prenode = NULL ;//第二个节点的pre域指向 NULL
free(tmp_node);
printf("释放结束\n");
}
//删除尾节点
void delete_tail_node(struct DoublyLinkList* list )
{
if(list == NULL)
{
printf("链表为空\n");
return ;
}
struct node * current_node = list->tail ;
struct node * tmp_node = NULL ;
printf("被删除节点地址为:%p\n",current_node);
tmp_node = current_node ; //要被释放的节点
printf("被释放的节点地址为:%p\n",tmp_node);
list->tail = current_node->prenode ;//下一个节点给到头结点
current_node->prenode->nextnode = NULL ;//第二个节点的pre域指向 NULL
free(tmp_node);
printf("释放结束\n");
}
//根据值删除节点(删除第一个匹配的)
void delete_node_by_data(struct DoublyLinkList* list , int node_value )
{
struct node * current_node = list->head ;
struct node * tmp_node = NULL ;
while(current_node->data != node_value)
{
current_node = current_node->nextnode ;
}
printf("被删除节点地址为:%p\n",current_node);
tmp_node = current_node ; //要被释放的节点
printf("被释放的节点地址为:%p\n",tmp_node);
current_node->prenode->nextnode = current_node->nextnode ;//把删除节点的下一个节点地址给到删除节点上一个节点的next域
current_node->nextnode->prenode = current_node->prenode ;//把删除节点的前一个节点的地址给到删除节点的下一个节点的pre域
free(tmp_node);
list->size--;
printf("释放结束,size大小为:%d\n",list->size);
}
//清空整个链表
void delete_list_all(struct DoublyLinkList* list )
{
if(list == NULL)
{
printf("链表为空\n");
return ;
}
struct node * current_node = list->head ;
while(current_node != NULL)
{
current_node->data = 0;
current_node = current_node->nextnode ;
}
}
//根据data值,查找节点地址
struct node find_node_by_data(struct DoublyLinkList list , int node_value )
{
struct node * current_node = list->head ;
struct node * tmp_node = NULL ;
while(current_node != NULL )
{
if(current_node->data == node_value)
{
printf("找到节点,节点值为:%d\n",current_node->data);
break ;
}
current_node = current_node->nextnode ;
}
printf("找到节点,节点地址值为:%p\n",current_node);
return current_node;
}
//打印一个链表,从头到尾
void print_list_head(struct DoublyLinkList* list) {
if (list == NULL) {
printf("链表为空!\n");
return;
}
struct node *current_node = list->head;
printf("链表(从头到尾):");
while (current_node != NULL) {
printf("%d", current_node->data);
if (current_node->nextnode != NULL) {
printf(" <-> ");
}
current_node = current_node->nextnode;
}
printf("\n");
}
//打印一个链表,从尾到头
void print_list_tail(struct DoublyLinkList* list) {
if (list == NULL) {
printf("链表为空!\n");
return;
}
struct node* current = list->tail;
printf("链表(从尾到头):");
while (current != NULL) {
printf("%d", current->data);
if (current->prenode != NULL) {
printf(" <-> ");
}
current = current->prenode;
}
printf("\n");
}
//释放一个链表
void lease_list_node(struct DoublyLinkList * list_node)
{
struct node *current = list_node->head ;
struct node *tmp_node = NULL ;
while(current != NULL)
{
tmp_node = current ;//准备释放的节点
current = current->nextnode ;//记录并跳到下一个节点
printf("---释放的地址为:%p---\n",tmp_node);
free(tmp_node);
}
}
int main()
{
struct DoublyLinkList *node1;
node1 = create_none_list();
append_node(node1,66);//在链表尾部添加节点
append_node(node1,88);//在链表尾部添加节点
preappend_node(node1,33);//在链表头部添加节点
preappend_node(node1,44);//在链表头部添加节点
print_list_head(node1);//打印链表
// delete_local_node(node1,3);//删除指定位置的节点
// delete_head_node(node1);//删除头节点
// delete_tail_node(node1);//删除尾节点
// delete_node_by_data(node1 ,33);//根据值删除节点(删除第一个匹配的)
// delete_list_all(node1);//清空整个链表
// find_node_by_data(node1,66);//根据data值,查找节点地址
add_node_in_list(node1,3,55);//插入节点到指定位置,eg:position == 2:新节点作为第2个几点
print_list_head(node1);//打印链表,从头到尾
print_list_tail(node1);//打印一个链表,从尾到头
lease_list_node(node1);//释放链表
}
//实现反转链表功能
//
//实现排序功能
//
//实现合并两个链表的功能
//
//实现循环双链表(尾节点指向头节点)