最近有时间看了数据结构的双向链表,其实和单向链表的规则是一样的,只不过在定义节点的时候比单向链表多定义i一个指向前一个节点的指针就可以了,在插入节点和删除节点的时候要注意,画图是最好的方法。
双向使用的时候重要的是获得链表头和链表尾,下面有获取的相关函数。
// copyright reserved by GongXu
// doubly linked list for simple using
#include<stdio.h>
#include<stdlib.h>
/*双向链表的关键是在节点上定义两个指针,一个指向前一个节点,另一个指向后一个节点*/
typedef int Data_type;
struct Node_doubly {
Data_type data;
struct Node_doubly* prev;
struct Node_doubly* next;
};
typedef struct Node_doubly* Node_p;
/*创造一个链表返回头结点*/
Node_p create_list(){
Node_p list_head = (Node_p)malloc(sizeof(struct Node_doubly));
list_head->prev = NULL;
list_head->next = NULL;
return list_head;
}
/*创建一个链表的节点,也就是开辟一个内存空间存储节点的数据*/
Node_p create_list_node(Data_type data){
Node_p new_node = malloc(sizeof(struct Node_doubly));
new_node->data = data;
return new_node;
};
/*在链表的头部位置添加数据*/
void insert_node_by_head (Node_p list,Data_type data){
Node_p new_node = create_list_node(data);
//插入时已经有节点
if (list->next){
list->next->prev = new_node;
new_node->next = list->next;
new_node->prev = list;
list->next = new_node;
}
// 插入的时候没有节点,只有首节点
else{
list->next = new_node;
new_node->prev = list;
new_node->next = NULL;
}
}
/*在链表的头部位置删除节点*/
void delete_node_by_head(Node_p list){
Node_p ptr = list->next;
list->next = ptr->next;
free(ptr);
}
/*在特定的数据点删除链表节点*/
void delete_node_by_pos(Node_p list, Data_type pos){
Node_p p_for = list;
Node_p p_aft = list->next;
while (p_aft->data != pos){
p_for = p_aft;
p_aft = p_aft->next;
if (p_aft == NULL){
printf("Not finding Positon to delete\n ");
return;
}
}
Node_p ptr = p_aft->next;
p_for->next = ptr;
ptr->prev = p_for;
free(p_aft);
}
/*返回双向链表的尾节点*/
Node_p get_lastNode(Node_p list){
Node_p ptr = list->next;
Node_p ptr_after = ptr;
if (ptr){
while (ptr != NULL){
ptr_after = ptr;
ptr = ptr->next;
}
return ptr_after;
}
else
return list;
}
/*打印链表的全部数据,使用首节点开始打印*/
void print_list(Node_p list){
Node_p ptr = list->next;
while (ptr != NULL){
printf("%d\t", ptr->data);
ptr=ptr->next;
}
printf("\n");
}
/*打印链表的全部数据,使用尾节点开始打印*/
void print_list_with_last(Node_p last_list){
Node_p ptr = last_list;
while (ptr->prev != NULL){
printf("%d\t", ptr->data);
ptr = ptr->prev;
}
printf("\n");
}
/*销毁链表,主要是把申请的内存还给内存管理器*/
void destroy_list(Node_p list){
Node_p ptr = list;
Node_p ptr_q ;
while (ptr != NULL){
ptr_q=ptr->next;
ptr->next=ptr_q->next;
free(ptr_q);
ptr = ptr->next;
}
list = NULL;
}
/*程序的主函数*/
int main(void){
// 创建一个链表返回头结点
Node_p List_head=create_list();
// 插入数据
insert_node_by_head(List_head, 10);
insert_node_by_head(List_head, 11);
insert_node_by_head(List_head, 12);
insert_node_by_head(List_head, 13);
//显示数据头结点开始
print_list(List_head);
//使用尾节点显示数据
Node_p last_list = get_lastNode(List_head);
print_list_with_last(last_list);
print_list(List_head);
delete_node_by_head(List_head);
delete_node_by_head(List_head);
print_list(List_head);
delete_node_by_pos(List_head,11);
print_list(List_head);
//销毁链表
destroy_list(List_head);
print_list(List_head);
while (1);
}