1?? 用结构体定义一个节点
struct node
{
int data;
struct node *prev;
struct node *next;
};
2?? 建立一个双向链表
- 双向链表结构
- 类似单链表的头插法,我们创建一个节点插在链表头节点前面成为新的头结点:
struct node *insertHead(struct node *head)
{
struct node *new = (struct node *)malloc(sizeof(struct node));
new->prev = NULL;
new->next = NULL;
printf("input your new node data:");
scanf("%d", &(new->data));
if (head == NULL){
return new;
}else{
head->prev = new;
new->next = head;
return new;
}
}
struct node *insertTail(struct node *head)
{
struct node *end = head;
struct node *new = (struct node *)malloc(sizeof(struct node));
new->prev = NULL;
new->next = NULL;
printf("input your new node data:");
scanf("%d", &(new->data));
if (head == NULL)
{
return new;
}
while (end->next != NULL)
{
end = end->next;
}
end->next = new;
new->prev = end;
return head;
}
3??双向链表的遍历
- 因为链表是双向的,所以我们可以从头和尾两个方向遍历
- 从头节点开始遍历:
void printLinkH(struct node *head)
{
if (head == NULL){
printf("The list is empty.\n");
return;
}
while (head != NULL){
printf("%d\n", head->data);
head = head->next;
}
putchar('\n');
}
- 因为我们的创建函数返回的是头节点地址,所以我们写一个得到尾节点地址的函数
struct node *getTail(struct node *head)
{
while (head->next != NULL)
{
head = head->next;
}
return head;
}
- 从尾节点的遍历跟从头结点一样,只不过把next换成了prev
void printLinkT(struct node *tail)
{
if (tail == NULL)
{
printf("The list is empty.\n");
return;
}
while (tail != NULL)
{
printf("%d\n", tail->data);
tail = tail->prev;
}
putchar('\n');
}
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *prev;
struct node *next;
};
struct node *insertHead(struct node *head)
{
struct node *new = (struct node *)malloc(sizeof(struct node));
new->prev = NULL;
new->next = NULL;
printf("input your new node data:");
scanf("%d", &(new->data));
if (head == NULL)
{
return new;
}
else
{
head->prev = new;
new->next = head;
return new;
}
}
struct node *insertTail(struct node *head)
{
struct node *end = head;
struct node *new = (struct node *)malloc(sizeof(struct node));
new->prev = NULL;
new->next = NULL;
printf("input your new node data:");
scanf("%d", &(new->data));
if (head == NULL)
{
return new;
}
while (end->next != NULL)
{
end = end->next;
}
end->next = new;
new->prev = end;
return head;
}
struct node *getTail(struct node *head)
{
while (head->next != NULL)
{
head = head->next;
}
return head;
}
void printLinkH(struct node *head)
{
if (head == NULL)
{
printf("The list is empty.\n");
return;
}
while (head != NULL)
{
printf("%d\n", head->data);
head = head->next;
}
putchar('\n');
}
void printLinkL(struct node *tail)
{
if (tail == NULL)
{
printf("The list is empty.\n");
return;
}
while (tail != NULL)
{
printf("%d\n", tail->data);
tail = tail->prev;
}
putchar('\n');
}
int main()
{
int i = 0;
struct node *head1 = NULL;
struct node *head2 = NULL;
struct node *tail = NULL;
for (i = 0; i < 5; i++)
{
head1 = insertHead(head1);
}
printLinkH(head1);
for (i = 0; i < 5; i++)
{
head2 = insertTail(head2);
}
tail = getTail(head2);
printLinkH(head2);
printLinkL(tail);
return 0;
}
-
示意图 -
终端显示:
input your new node data:1
input your new node data:2
input your new node data:3
input your new node data:4
input your new node data:5
5
4
3
2
1
input your new node data:11
input your new node data:22
input your new node data:33
input your new node data:44
input your new node data:55
11
22
33
44
55
55
44
33
22
11
4??删除第n个节点
- 这里的方法很灵活,我的做法是用一个指针p遍历到第n个节点的后一个结点,然后把目标节点(p->prev)的prev赋值给p下节点的prev,把p的地址赋值给上上个节点的next,最后释放(free)掉目标节点就成了。
struct node *delNode(struct node *head, int num)
{
struct node *p = head;
if (num == 1){
head = head->next;
free(p);
return head;
}
while (num--){
if (p->next == NULL){
struct node *temp = p;
p->prev->next = NULL;
free(temp);
return head;
}
p = p->next;
}
p->prev->prev->next = p;
struct node *temp = p->prev;
p->prev = p->prev->prev;
free(temp);
return head;
}
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *prev;
struct node *next;
};
struct node *insertTail(struct node *head)
{
struct node *end = head;
struct node *new = (struct node *)malloc(sizeof(struct node));
new->prev = NULL;
new->next = NULL;
printf("input your new node data:");
scanf("%d", &(new->data));
if (head == NULL)
{
return new;
}
while (end->next != NULL)
{
end = end->next;
}
end->next = new;
new->prev = end;
return head;
}
void printLinkH(struct node *head)
{
if (head == NULL)
{
printf("The list is empty.\n");
return;
}
while (head != NULL)
{
printf("%d\n", head->data);
head = head->next;
}
putchar('\n');
}
struct node *delNode(struct node *head, int num)
{
struct node *p = head;
if (num == 1){
head = head->next;
free(p);
return head;
}
while (num--)
{
if (p->next == NULL){
struct node *temp = p;
p->prev->next = NULL;
free(temp);
return head;
}
p = p->next;
}
p->prev->prev->next = p;
struct node *temp = p->prev;
p->prev = p->prev->prev;
free(temp);
return head;
}
struct node *creatLink(struct node *head)
{
int num;
printf("input node num:");
scanf("%d", &num);
putchar('\n');
while (num--){
head = insertTail(head);
}
return head;
}
int main()
{
int n;
struct node *head = NULL;
head = creatLink(head);
printLinkH(head);
printf("input del num:");
scanf("%d", &n);
head = delNode(head, n);
putchar('\n');
printLinkH(head);
return 0;
}
input node num:6
input your new node data:1
input your new node data:2
input your new node data:3
input your new node data:4
input your new node data:5
input your new node data:6
1
2
3
4
5
6
input del num:4
1
2
3
5
6
5??在第n个节点后插入一个节点
- 创建一个新节点new,用一个指针p遍历到第n个节点的后一个节点,把new结点的地址给第n个节点(p->prev)的next,并让newt的prev指向n节点;把p的地址给new的next,最后再把new结点的地址给第p的prev就完成了
- 函数如下:
int insertnode(struct node *p, int num)
{
struct node *new = (struct node *)malloc(sizeof(struct node));
printf("input your new node data:");
scanf("%d", &(new->data));
while (num--){
if (p->next == NULL){
p->next = new;
new->prev = p;
new->next = NULL;
return 0;
}
p = p->next;
}
p->prev->next = new;
new->prev = p->prev;
new->next = p;
p->prev = new;
}
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *prev;
struct node *next;
};
struct node *insertTail(struct node *head)
{
struct node *end = head;
struct node *new = (struct node *)malloc(sizeof(struct node));
new->prev = NULL;
new->next = NULL;
printf("input your new node data:");
scanf("%d", &(new->data));
if (head == NULL)
{
return new;
}
while (end->next != NULL)
{
end = end->next;
}
end->next = new;
new->prev = end;
return head;
}
void printLinkH(struct node *head)
{
if (head == NULL)
{
printf("The list is empty.\n");
return;
}
while (head != NULL)
{
printf("%d\n", head->data);
head = head->next;
}
putchar('\n');
}
int insertnode(struct node *p, int num)
{
struct node *new = (struct node *)malloc(sizeof(struct node));
printf("input your new node data:");
scanf("%d", &(new->data));
while (num--){
if (p->next == NULL){
p->next = new;
new->prev = p;
new->next = NULL;
return 0;
}
p = p->next;
}
p->prev->next = new;
new->prev = p->prev;
new->next = p;
p->prev = new;
}
struct node *creatLink(struct node *head)
{
int num;
printf("input node num:");
scanf("%d", &num);
putchar('\n');
while (num--){
head = insertTail(head);
}
return head;
}
int main()
{
int n;
struct node *head = NULL;
head = creatLink(head);
printLinkH(head);
printf("input del num:");
scanf("%d", &n);
insertnode(head, n);
putchar('\n');
printLinkH(head);
return 0;
}
input node num:5
input your new node data:5
input your new node data:6
input your new node data:7
input your new node data:8
input your new node data:9
5
6
7
8
9
input insert num:3
input your new node data:666
5
6
7
666
8
9
|