所以,在这里我制作了一个双向链表,但我不想手动分配值(10、20、30),而是想制作一个 for 循环并以这种方式放置数据以使其高效。 我在单链表中做到了这一点,但这里没有发生同样的情况,只有backward_traversing函数起作用。 在这里给出代码。
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
int value;
struct Node *next_link;
struct Node *prev_link;
} Node;
Node *create_node(int value)
{
Node *new_node = malloc(sizeof(Node));
new_node->value = value;
new_node->next_link = NULL;
new_node->prev_link = NULL;
return new_node;
}
void forward_traversing(Node *head)
{
Node *temp = head;
while (temp != NULL)
{
printf("%d ", temp -> value);
temp = temp->next_link;
}
printf("\n");
}
void backward_traversing(Node *tail)
{
Node *temp = tail;
while (temp != NULL)
{
printf("%d ", temp->value);
temp = temp->prev_link;
}
printf("\n");
}
void show_first(Node *head)
{
printf("%d \n", head->value);
}
void show_last(Node *tail)
{
printf("%d \n", tail->value);
}
int main()
{
Node *head, *temp, *tail;
for (int i = 0; i <= 25; i++){
temp = create_node(i);
temp -> next_link = head;
head = temp;
}
forward_traversing(head);
backward_traversing(tail);
show_first(head);
show_last(tail);
return 0;
}
定义一个类型来保存列表的头指针和尾指针非常有用,因为某些函数可能需要更新头指针和尾指针。
基本操作包括:
可以编写函数来执行这些操作,如以下基于 OP 原始代码的示例所示(OP 的函数采用头指针或尾指针已更改为采用指向列表控制结构的指针):
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
int value;
struct Node *next_link;
struct Node *prev_link;
} Node;
typedef struct List
{
struct Node *head;
struct Node *tail;
} List;
Node *create_node(int value)
{
Node *new_node = malloc(sizeof(Node));
new_node->value = value;
new_node->next_link = NULL;
new_node->prev_link = NULL;
return new_node;
}
Node *node_next(Node *node)
{
return node->next_link;
}
Node *node_prev(Node *node)
{
return node->prev_link;
}
void free_node(Node *node)
{
free(node);
}
void list_init(List *list)
{
list->head = NULL;
list->tail = NULL;
}
Node *list_first(List *list)
{
return list->head;
}
Node *list_last(List *list)
{
return list->tail;
}
/* Note: existingnode assumed to be on the list if non-null */
/* Note: if existingnode is null, newnode will be prepended to the list */
void list_insert_before(List *list, Node * restrict existingnode,
Node * restrict newnode)
{
if (newnode)
{
Node *prev;
if (existingnode == NULL)
{
/* newnode will be prepended before head (if it exists) */
existingnode = list->head;
}
if (existingnode)
{
prev = existingnode->prev_link;
existingnode->prev_link = newnode;
}
else
{
/* list is empty */
prev = NULL;
list->tail = newnode;
}
newnode->prev_link = prev;
newnode->next_link = existingnode;
if (prev)
{
prev->next_link = newnode;
}
else
{
/* newnode being prepended to the list */
list->head = newnode;
}
}
}
void list_prepend(List *list, Node *node)
{
/* Note: list->head may be null */
list_insert_before(list, list->head, node);
}
void list_append(List *list, Node *node)
{
if (node)
{
node->next_link = NULL;
node->prev_link = list->tail;
if (list->tail)
{
list->tail->next_link = node;
}
else
{
/* list is empty */
list->head = node;
}
list->tail = node;
}
}
/* Note: existingnode assumed to be on the list if non-null */
/* Note: if existingnode is null, newnode will be appended to the list */
void list_insert_after(List *list, Node * restrict existingnode,
Node * restrict newnode)
{
if (existingnode == NULL || existingnode == list->tail)
{
list_append(list, newnode);
}
else
{
list_insert_before(list, existingnode->next_link, newnode);
}
}
/* Note: node assumed to be on the list if non-null */
void list_remove_node(List *list, Node *node)
{
if (node)
{
Node *next = node->next_link;
Node *prev = node->prev_link;
if (next)
{
next->prev_link = prev;
}
else
{
list->tail = prev;
}
if (prev)
{
prev->next_link = next;
}
else
{
list->head = next;
}
}
}
Node *list_remove_first(List *list)
{
Node *node = list_first(list);
list_remove_node(list, node);
return node;
}
Node *list_remove_last(List *list)
{
Node *node = list_last(list);
list_remove_node(list, node);
return node;
}
void free_list_nodes(List *list)
{
Node *temp;
while ((temp = list_remove_first(list)) != NULL)
{
free_node(temp);
}
}
void forward_traversing(List *list)
{
Node *temp = list_first(list);
while (temp != NULL)
{
printf("%d ", temp->value);
temp = temp->next_link;
}
printf("\n");
}
void backward_traversing(List *list)
{
Node *temp = list_last(list);
while (temp != NULL)
{
printf("%d ", temp->value);
temp = temp->prev_link;
}
printf("\n");
}
void show_first(List *list)
{
Node *head = list_first(list);
if (head)
{
printf("%d \n", head->value);
}
else
{
printf("(empty)\n");
}
}
void show_last(List *list)
{
Node *tail = list_last(list);
if (tail)
{
printf("%d \n", tail->value);
}
else
{
printf("(empty)\n");
}
}
int main()
{
List list;
Node *node;
int i;
list_init(&list);
for (i = 10; i < 50; i += 10)
{
node = create_node(i);
if (node)
{
list_append(&list, node);
}
}
printf("Initial list\n");
forward_traversing(&list);
backward_traversing(&list);
printf("Remove first node\n");
node = list_remove_first(&list); /* (10), 20, 30, 40 */
forward_traversing(&list);
backward_traversing(&list);
printf("Prepend removed node to start of list\n");
list_prepend(&list, node); /* 10, 20, 30, 40 */
forward_traversing(&list);
backward_traversing(&list);
printf("Remove last node\n");
node = list_remove_last(&list); /* 10, 20, 30, (40) */
forward_traversing(&list);
backward_traversing(&list);
printf("Append removed node to end of list\n");
list_append(&list, node); /* 10, 20, 30, 40 */
forward_traversing(&list);
backward_traversing(&list);
printf("Remove third node\n");
node = node_next(node_next(list_first(&list))); /* (30) */
list_remove_node(&list, node); /* 10, 20, 40 */
forward_traversing(&list);
backward_traversing(&list);
printf("Insert removed node after second node\n");
list_insert_after(&list, node_next(list_first(&list)), node);
/* 10, 20, 30, 40 */
forward_traversing(&list);
backward_traversing(&list);
printf("Remove previous (third) node again\n");
list_remove_node(&list, node); /* 10, 20, 40 */
forward_traversing(&list);
backward_traversing(&list);
printf("Insert removed node before third (original fourth) node\n");
list_insert_before(&list, node_next(node_next(list_first(&list))),
node); /* 10, 20, 30, 40 */
forward_traversing(&list);
backward_traversing(&list);
printf("First node\n");
show_first(&list);
printf("Last node\n");
show_last(&list);
free_list_nodes(&list);
return 0;
}