寫在前面的話:
- 版權聲明:本文爲博主原創文章,轉載請註明出處!
- 博主是一個小菜鳥,並且非常玻璃心!如果文中有什麼問題,請友好地指出來,博主查證後會進行更正,啾咪~~
- 每篇文章都是博主現階段的理解,如果理解的更深入的話,博主會不定時更新文章。
- 本文最後更新時間:2020.4.30
正文開始
在單鏈表中,我們設了next指針,這使得我們查找下一個結點的時間複雜度爲O(1),但是如果我們想要查找的是上一個結點,那麼最壞的時間複雜度爲O(n),因爲我們每次都要從頭開始遍歷查找。
爲了克服單向性這一缺點,便有人設計出了雙向鏈表。雙向鏈表是在單鏈表的每個結點中,再設置一個指向其前驅結點的指針域。所以在雙向鏈表中的結點都有兩個指針域,一個指向直接後繼,另一個指向直接前驅。
雙向循環鏈表中的指針都是成對出現的:你的next指向我,我的prior指向你。
1. 定義數據結構
/* =================
定義鏈表數據結構
================= */
struct node
{
int num;
struct node *prior; //prior存放上一個結點的地址
struct node *next; //next存放下一個結點的地址
};
2. 設頭結點
#include <stdio.h>
#include <stdlib.h>
/* =================
定義鏈表數據結構
================= */
struct node
{
int num;
struct node *prior; //prior存放上一個結點的地址
struct node *next; //next存放下一個結點的地址
};
typedef struct node Node;
typedef Node * Dlink;
/* ===============
功能:設頭結點
返回:void
=============== */
void init_d_link(Dlink *head)
{
*head = (Dlink)malloc(sizeof(Node)); //爲頭結點分配空間
(*head)->prior = *head;
(*head)->next = *head;
}
int main()
{
Dlink head;
init_d_link(&head);
return 0;
}
3. 插入
3.1 頭插
#include <stdio.h>
#include <stdlib.h>
/* =================
定義鏈表數據結構
================= */
struct node
{
int num;
struct node *prior; //prior存放上一個結點的地址
struct node *next; //next存放下一個結點的地址
};
typedef struct node Node;
typedef Node * Dlink;
/* ===============
功能:設頭結點
返回:void
=============== */
void init_d_link(Dlink *head)
{
*head = (Dlink)malloc(sizeof(Node)); //爲頭結點分配空間
(*head)->prior = *head;
(*head)->next = *head;
}
/* =====================
功能:從頭部插入結點
返回:void
===================== */
void insert_head_node(Dlink newnode,Dlink head)
{
newnode->next = head->next;
head->next->prior = newnode;
head->next = newnode;
newnode->prior = head;
}
/* ================
功能:打印鏈表
返回:void
================ */
void display_link(Dlink head)
{
Dlink temp = head->next;
while (temp != head) //遍歷鏈表
{
printf("%d\n", temp->num);
temp = temp->next;
}
}
int main()
{
Dlink head;
Dlink newnode;
init_d_link(&head);
for (int i = 0; i < 10; i++)
{
newnode = (Dlink)malloc(sizeof(Node)); //爲結點分配空間
newnode->num = i + 1; //爲結點數據域賦值
insert_head_node(newnode, head); //頭插
}
printf("頭插後的鏈表爲 : \n");
display_link(head); //打印鏈表
return 0;
}
運行結果:
頭插後的鏈表爲 :
10
9
8
7
6
5
4
3
2
1
3.2 尾插
#include <stdio.h>
#include <stdlib.h>
/* =================
定義鏈表數據結構
================= */
struct node
{
int num;
struct node *prior; //prior存放上一個結點的地址
struct node *next; //next存放下一個結點的地址
};
typedef struct node Node;
typedef Node * Dlink;
/* ===============
功能:設頭結點
返回:void
=============== */
void init_d_link(Dlink *head)
{
*head = (Dlink)malloc(sizeof(Node)); //爲頭結點分配空間
(*head)->prior = *head;
(*head)->next = *head;
}
/* =====================
功能:從尾部插入結點
返回:void
===================== */
void insert_tail_node(Dlink newnode, Dlink head)
{
head->prior->next = newnode;
newnode->prior = head->prior;
newnode->next = head;
head->prior = newnode;
}
/* ================
功能:打印鏈表
返回:void
================ */
void display_link(Dlink head)
{
Dlink temp = head->next;
while (temp != head) //遍歷鏈表
{
printf("%d\n", temp->num);
temp = temp->next;
}
}
int main()
{
Dlink head;
Dlink newnode;
init_d_link(&head);
for (int i = 0; i < 10; i++)
{
newnode = (Dlink)malloc(sizeof(Node)); //爲結點分配空間
newnode->num = i + 1; //爲結點數據域賦值
insert_tail_node(newnode, head); //尾插
}
printf("尾插後的鏈表爲 : \n");
display_link(head); //打印鏈表
return 0;
}
運行結果:
尾插後的鏈表爲 :
1
2
3
4
5
6
7
8
9
10
3.3 從中間插入
#include <stdio.h>
#include <stdlib.h>
/* =================
定義鏈表數據結構
================= */
struct node
{
int num;
struct node *prior; //prior存放上一個結點的地址
struct node *next; //next存放下一個結點的地址
};
typedef struct node Node;
typedef Node * Dlink;
/* ===============
功能:設頭結點
返回:void
=============== */
void init_d_link(Dlink *head)
{
*head = (Dlink)malloc(sizeof(Node)); //爲頭結點分配空間
(*head)->prior = *head;
(*head)->next = *head;
}
/* =====================
功能:從尾部插入結點
返回:void
===================== */
void insert_tail_node(Dlink newnode, Dlink head)
{
head->prior->next = newnode;
newnode->prior = head->prior;
newnode->next = head;
head->prior = newnode;
}
/* =====================
功能:從中間插入結點
返回:是否成功
===================== */
int insert_mid_node(Dlink newnode, Dlink head,int num)
{
Dlink temp = head->next;
while (temp != head) //遍歷鏈表
{
if (temp->num == num) //判斷是否是要找的結點
{
newnode->next = temp->next;
temp->next->prior = newnode;
temp->next = newnode;
newnode->prior = temp;
return 0;
}
temp = temp->next;
}
return -1;
}
/* ================
功能:打印鏈表
返回:void
================ */
void display_link(Dlink head)
{
Dlink temp = head->next;
while (temp != head) //遍歷鏈表
{
printf("%d\n", temp->num);
temp = temp->next;
}
}
int main()
{
Dlink head;
Dlink newnode;
init_d_link(&head);
for(int i = 0; i < 10; i++)
{
newnode = (Dlink)malloc(sizeof(Node)); //爲結點分配空間
newnode->num = i + 1; //爲結點數據域賦值
insert_tail_node(newnode, head); //尾插
}
newnode = (Dlink)malloc(sizeof(Node)); //爲新結點分配空間
newnode->num = 11; //數據域賦值
insert_mid_node(newnode, head, 5); //在數據域爲5的結點後插入新結點
printf("從中間插入後的鏈表爲 : \n");
display_link(head); //打印鏈表
return 0;
}
運行結果:
從中間插入後的鏈表爲 :
1
2
3
4
5
11
6
7
8
9
10
4. 刪除結點
#include <stdio.h>
#include <stdlib.h>
/* =================
定義鏈表數據結構
================= */
struct node
{
int num;
struct node *prior; //prior存放上一個結點的地址
struct node *next; //next存放下一個結點的地址
};
typedef struct node Node;
typedef Node * Dlink;
/* ===============
功能:設頭結點
返回:void
=============== */
void init_d_link(Dlink *head)
{
*head = (Dlink)malloc(sizeof(Node)); //爲頭結點分配空間
(*head)->prior = *head;
(*head)->next = *head;
}
/* =====================
功能:從尾部插入結點
返回:void
===================== */
void insert_tail_node(Dlink newnode, Dlink head)
{
head->prior->next = newnode;
newnode->prior = head->prior;
newnode->next = head;
head->prior = newnode;
}
/* ===============
功能:刪除結點
返回:是否成功
=============== */
int delete_node(int num, Dlink head)
{
Dlink temp = head->next;
while (temp != head) //遍歷鏈表
{
if (temp->num == num) //判斷是否是要刪除的結點
{
temp->prior->next = temp->next;
temp->next->prior = temp->prior;
free(temp); //釋放
temp = NULL; //置空
return 0;
}
temp = temp->next;
}
return -1;
}
/* ================
功能:打印鏈表
返回:void
================ */
void display_link(Dlink head)
{
Dlink temp = head->next;
while (temp != head) //遍歷鏈表
{
printf("%d\n", temp->num);
temp = temp->next;
}
}
int main()
{
Dlink head;
Dlink newnode;
init_d_link(&head);
for(int i = 0; i < 10; i++)
{
newnode = (Dlink)malloc(sizeof(Node)); //爲結點分配空間
newnode->num = i + 1; //爲結點數據域賦值
insert_tail_node(newnode, head); //尾插
}
delete_node(7, head); //刪除數據域爲7的結點
printf("刪除數據域爲7的結點後的鏈表爲 : \n");
display_link(head); //打印鏈表
return 0;
}
運行結果:
刪除數據域爲7的結點後的鏈表爲 :
1
2
3
4
5
6
8
9
10