双向链表
维基百科
双向链表,又称为双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
头插法入结点图解
一、定义链表结点结构体
头文件
#include <stdio.h>
#include <stdlib.h>//提供malloc()原型
#include <string.h>//提供memset()原型
结构体(定义别名方便书写)
typedef struct Double_List_Node{
int data;//数据域
struct Double_List_Node *next;//指针域
struct Double_List_Node *prev;
}L;
二、创建链表(头结点)
L *create_List()
{
L *head_Node = (L *)malloc(sizeof(L));
memset(head_Node, 0, sizeof(L));
head_Node->next = NULL;
head_Node->prev = NULL;
return head_Node;
}
三、创建新结点
L *create_Node(int Data)
{
L *new_Node = (L *)malloc(sizeof(L));
memset(new_Node, 0, sizeof(L));
new_Node->data = Data;
new_Node->next = NULL;
new_Node->prev = NULL;
return new_Node;
}
四、头插法插入结点
void top_insert(L *head_Node, L *new_Node)
{
new_Node->next = head_Node->next;
if(head_Node->next != NULL){
head_Node->next->prev = new_Node;
}
new_Node->prev = head_Node;
head_Node->next = new_Node;
}
五、尾插法插入结点
void tail_insert(L *head_Node, L *new_Node)
{
while(head_Node->next != NULL){
head_Node = head_Node->next;//找到链表中的最后一个结点
}
new_Node->prev = head_Node;
head_Node->next = new_Node;
}
六、删除结点
int delete_Node(L *head_Node, int Data)
{
while(head_Node->next != NULL){
head_Node = head_Node->next;
if(head_Node->data == Data)//找到要删除的结点了!
{
if(head_Node->next == NULL)//要删除的结点是最后一个
{
head_Node->prev->next = NULL;
free(head_Node);
}
else//要删除的结点不是最后一个
{
head_Node->prev->next = head_Node->next;
head_Node->next->prev = head_Node->prev;
free(head_Node);
}
return 0;
}
}
printf("没有找到要删除的结点!\n");
return -1;
}
七、打印链表
void print_List(L *head_Node)
{
while(head_Node->next != NULL){
head_Node = head_Node->next;
printf("%d ", head_Node->data);
}
printf("\n");
}
八、逆序打印链表
void rev_Print_List(L *head_Node){
while(head_Node->next != NULL){
head_Node = head_Node->next;//找到最后一个结点
}
while(head_Node->prev != NULL){
printf("%d ", head_Node->data);
head_Node = head_Node->prev;//从最后一个结点开始遍历
}
printf("\n");
}
加入主函数进行测试
#include <stdio.h>
#include <stdlib.h>//提供malloc()原型
#include <string.h>//提供memset()原型
typedef struct Double_List_Node{
int data;//数据域
struct Double_List_Node *next;//指针域
struct Double_List_Node *prev;
}L;
//创建链表
L *create_List()
{
L *head_Node = (L *)malloc(sizeof(L));
memset(head_Node, 0, sizeof(L));
head_Node->next = NULL;
head_Node->prev = NULL;
return head_Node;
}
//创建链表结点
L *create_Node(int Data)
{
L *new_Node = (L *)malloc(sizeof(L));
memset(new_Node, 0, sizeof(L));
new_Node->data = Data;
new_Node->next = NULL;
new_Node->prev = NULL;
return new_Node;
}
//头插法
void top_insert(L *head_Node, L *new_Node)
{
new_Node->next = head_Node->next;
if(head_Node->next != NULL){
head_Node->next->prev = new_Node;
}
new_Node->prev = head_Node;
head_Node->next = new_Node;
}
//尾插法
void tail_insert(L *head_Node, L *new_Node)
{
while(head_Node->next != NULL){
head_Node = head_Node->next;//找到链表中的最后一个结点
}
new_Node->prev = head_Node;
head_Node->next = new_Node;
}
//打印链表
void print_List(L *head_Node)
{
while(head_Node->next != NULL){
head_Node = head_Node->next;
printf("%d ", head_Node->data);
}
printf("\n");
}
//逆序打印
void rev_Print_List(L *head_Node){
while(head_Node->next != NULL){
head_Node = head_Node->next;
}
while(head_Node->prev != NULL){
printf("%d ", head_Node->data);
head_Node = head_Node->prev;
}
printf("\n");
}
//删除结点
int delete_Node(L *head_Node, int Data)
{
while(head_Node->next != NULL){
head_Node = head_Node->next;
if(head_Node->data == Data)//找到要删除的结点了!
{
if(head_Node->next == NULL)//要删除的结点是最后一个
{
head_Node->prev->next = NULL;
free(head_Node);
}
else//要删除的结点不熟最后一个
{
head_Node->prev->next = head_Node->next;
head_Node->next->prev = head_Node->prev;
free(head_Node);
}
return 0;
}
}
printf("没有找到要删除的结点!\n");
return -1;
}
int main()
{
L *list = create_List();
top_insert(list, create_Node(10));
top_insert(list, create_Node(20));
top_insert(list, create_Node(30));
tail_insert(list, create_Node(10));
tail_insert(list, create_Node(20));
tail_insert(list, create_Node(30));
delete_Node(list, 30);
delete_Node(list, 20);
print_List(list);
rev_Print_List(list);
free(list);
return 0;
}