【发布时间】:2018-10-16 11:55:48
【问题描述】:
此代码的目的是管理插入和删除以及可视化。我只想知道我是否正确地做所有事情,让我知道是否有更多可能的方法来做到这一点。这是我的第一次尝试,我没有遵循任何教程。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node {
int n;
struct Node *next;
struct Node *prev;
}TNode;
typedef TNode* Node;
void NewNode(Node *pp, int n)
{
Node temp, last;
temp = (Node)malloc(sizeof(struct Node));
temp->n = n;
temp->next = temp;
temp->prev = temp;
if(*pp != NULL)
{
last = (*pp)->prev;
temp->next = (*pp);
temp->prev = last;
last->next = (*pp)->prev = temp;
}
*pp = temp;
}
void ViewList(Node head)
{
if(head == NULL)
{
return;
}
Node node = head->prev;
do
{
printf("Curr: %d\n", node->n);
node = node->prev;
}while(node != head->prev);
}
void ReadData(Node * head, int * n)
{
printf("\nInsert a number:");
scanf("%d", n);
NewNode(head, *n);
}
Node SearchNode(Node head)
{
int d;
printf("\nElement to Delete:");
scanf("%d", &d);
while(head != NULL)
{
if(head->n == d)
{
return head;
}
head = head->next;
}
printf("\nNo Element [%d] Found", d);
return NULL;
}
void Delete(Node * head)
{
Node del = SearchNode(*head);
if(*head == NULL || del == NULL)
{
return;
}
if(*head == del && del->next == *head)
{
*head = NULL;
free(del);
return;
}
if(*head == del)
{
*head = del->next;
del->prev->next = *head;
(*head)->prev = del->prev;
free(del);
return;
}
if((*head)->prev == del)
{
(*head)->prev = del->prev;
del->prev->next = *head;
free(del);
return;
}
del->next->prev = del->prev;
del->prev->next = del->next;
free(del);
}
int Menu()
{
int c;
printf("\n*** M E N U ***\n"
"1 - New Node\n"
"2 - View List\n"
"3 - Delete\n"
"0 - Exit\n"
"\n>> ");
scanf(" %d", &c);
return c;
}
int main()
{
int c,n;
Node head = NULL;
do {
c = Menu();
switch (c)
{
case 1: ReadData(&head, &n); break;
case 2: ViewList(head); break;
case 3: Delete(&head); break;
default: c = 0;
}
} while (c != 0);
return 0;
}
我如何测试这是否是一个真正的循环双向链表而不是一个简单的双向链表?
【问题讨论】:
-
对于删除一个节点,你不需要知道它是否是一个循环列表,只要在你取消引用它们之前确保所有指针都是非空的(并记住要 initialize 所有指向 null 的指针)。
-
我不知道这是否是您要求的,但我发现有人似乎已经在 github 中完成了此算法。也许这也可以帮助您比较Circular Double Linked List in C
-
至于移除本身,我建议你先在纸上做:画一些正方形(代表节点)和它们之间的箭头(代表链接)。在尝试使用代码之前,请尝试找出一种在纸上“取消链接”的方法。当您开始编码时,请分小步进行,在每个步骤之间进行测试和调试。
-
您的问题是:“删除双循环链表中节点的正确方法是什么?” 还是 “我如何测试这是否是一个真正的循环双向链表而不是一个简单的双向链表?” 这是两个非常不同的问题。顺便说一句,删除一个你不需要知道它是否是循环列表的节点。
-
顺便说一句:你隐藏的指针类型和 typedefs 只会增加混乱。我会把它们放在一起。
标签: c nodes doubly-linked-list circular-list